GuideBringing a campaign from Discord

Bringing a campaign from Discord

Linking a server, reading a channel back out, saying who each voice in it is, and what arrives when you press the button.
GMs

A group that has been playing on Discord for three years has its history in the wrong building. This is how it moves: threads and posts, on the dates they were written, attributed to the people who wrote them.

What actually happens

Four steps, and the first three write nothing to your campaign. You install a bot that can read a server’s history, you point it at one channel and see what importing that channel would cost, you say who each voice in it is, and then you press the button.

All of it is on the campaign’s Settings → Discord tab, and all of it needs you to be the owner or a co-GM. You work a channel at a time, which is how a server actually moves — scan four channels, map them when you have a minute, bring them over in whatever order suits, in one sitting or across several.

Linking the server

Installing adds a bot to your Discord server. It reads message history and does nothing else: it never posts, never moderates, and cannot change anything there. You need to be able to add a bot to that server, which on Discord means Manage Server.

Installing is itself the act that connects the two — there is no code to copy across, and one server belongs to one campaign.

Reading a channel back out, before you commit

A scan writes nothing. It reads the channel and tells you what an import would be: how many messages, how many attachments, and how much those weigh. That is a separate step on purpose — the number people are surprised by is the attachments, and finding that out afterwards is finding it out too late.

Three things to pick.

  1. The channel

    Text channels, announcement channels and forums. Voice and stage channels hold no history to read and are not offered.

  2. How it is laid out

    This is the choice that decides what the import looks like, and it is the one thing on the screen nothing can check for you.

    A forum channel
    Every forum post becomes its own thread here, keeping its name.
    Threads in it
    Every Discord thread becomes its own thread here. Messages posted in the channel itself, outside any thread, are counted too.
    One long channel
    The whole channel becomes a single thread, in order, from the beginning.

    Getting it wrong is visible rather than costly: a forum scanned as One long channel comes back empty, because a forum holds no messages of its own. The channel list marks which ones are forums.

  3. Which board it lands on

    An import needs somewhere to go, so a campaign with no boards makes one first. A board of its own is usually easier to live with afterwards than three years of Discord mixed into a board people are already writing on.

Saying who everybody is

The scan collects every distinct voice in the channel and asks one question about each. Which question depends on what the voice is, and that distinction is the part of this screen worth understanding before you meet it.

Ordinary accounts point at members. Anybody at your table who has signed in here with Discord is filled in before the screen is drawn, so you are confirming rather than matching numbers by hand.

Names a proxy bot wrote under point at characters. Tupperbox and PluralKit delete the human’s message and re-post it through a webhook wearing the character’s name — so in the raw history, most in-character writing was written by a bot. Pointing one of those at a character carries its posts to whoever plays it, because a character has an owner. A character whose name matches is offered rather than assumed.

Leaving a voice unclaimed is the ordinary case

Most of the people in a three-year channel do not have accounts here, and their writing arrives all the same — carrying the Discord name and face it was written under, marked as a voice carried over rather than drawn as a member of your campaign. It is not an error and it does not have to be resolved before you import.

You can come back to this screen whenever you like. Somebody who turns up here in six months cannot yet claim their own posts, so mapping them stays your job.

The import

Press the button and watch a channel become threads and posts. Four things it does that are worth knowing before you judge the result:

Original dates
A thread is dated when it was written rather than today, so three years sort into the board’s past instead of piling up at the top as though it all happened this afternoon.
Messages rejoined
Discord cuts a message at 2,000 characters, so one written paragraph is routinely three messages. Consecutive messages from one voice, within five minutes of each other, are put back together into the post they were split out of.
A batch at a time
Twenty thousand messages is not one request that has to survive twenty thousand messages. Close the tab, sleep the laptop or lose the connection and it picks itself up within about five minutes and finishes without you.
Safe to run twice
Running it again brings over whatever has been written on Discord since, and rewrites nothing. Each message is remembered by its own Discord id, so nothing arrives twice however many times it is asked for.

Discord’s formatting mostly survives untouched, because it is the syntax this site already writes in: bold, italics, strikethrough, quotes, inline code and fenced blocks all arrive as themselves. What gets rewritten is the four things Discord stores as numbers — mentions, channels, roles and custom emoji — which would otherwise land in the middle of a sentence as <@81384788765712384>.

The files that come with it

A picture posted in the channel arrives in the post it was posted in, drawn where it was dropped, so a scene that turns on somebody producing a map is that scene again rather than a note about one. Copied files go into the campaign’s own private storage, readable by the people at that table and nobody else.

What comes across: PNG, JPEG, WebP and GIF; PDF, plain text and Markdown. Up to 10 MB each.

What stays on Discord: video, audio, archives, and anything larger. The post names what it left behind, so a missing file is visible rather than quietly absent.

It counts against the campaign’s storage

500 MB on a free campaign, 25 GB on premium. Nobody fills that by hand a map at a time; five years of somebody else’s channel arriving at once is the first thing that can.

Running out does not stop the import. It carries on writing the posts — which is what an import is for, and is free — stops copying files, and says plainly that it has run out of room and what would change that.

The bot, once it is in the server

Typing /hearthhall in a server it has been added to gets a reply the whole channel can see: a link to the campaign that server is linked to, or an explanation of what this site is and how a GM links one, when nobody has.

The reply gives away nothing the link does not. That link opens for members of the campaign and tells everybody else there is no such campaign — exactly as it would if they had guessed the address.

If somebody does not want their name here

An import copies the display name and avatar of everybody who ever wrote in the channel, most of whom were never asked. So there is a route for them, and it needs no Hearthhall account: write to support@hearthhall.com from the email address on the Discord account, or say which Discord username and which server the import came from.

Remove my name is what happens by default: the Discord id, display name and avatar go, and the posts stay, attributed to nobody — they read as written by someone from Discord rather than by anybody. Remove my messages deletes the imported posts and their files as well.

The narrower remedy is offered first because of what the wider one costs other people: an imported scene is usually a conversation, and deleting one voice from it leaves the others answering somebody who is no longer there. That is a reason to offer them in that order and to say why — not a reason to refuse the second.

The bot’s own privacy notice is the full version: what it reads, what it cannot reach, how long each part is kept, and the one thing that survives a name being removed — a scrambled, one-way fingerprint of the Discord id, different in every campaign, kept only so that importing the same channel again cannot quietly put the name back.