Changelog
The guide covers the Discord import
- NewA guide page on bringing a campaign over from Discord, at /guide/discord. The feature shipped with its explanation spread across the screens you meet it on and a privacy notice — which is enough to get through it once you have started, and no help at all to somebody deciding whether to. It sets out the whole path: what installing the bot does and does not permit, why the scan is a separate step from the import, how to pick the shape of a channel, why a name a proxy bot wrote under points at a character rather than at a member, what the import does to dates and to messages Discord split in half, which files come and which stay behind, and what happens to the storage a campaign has. The last section is written for somebody who has no account here and never asked to be copied in: what to write to, and the difference between having your name taken off and having the writing taken down. It is reachable from the three places the question comes up: the Discord tab where a GM is already standing, and twice from “Running a game” — once where the setup steps tell you to write the page that says what this is, which a campaign with three years of channel behind it has already written somewhere else, and once where getting people in is about recruiting strangers rather than moving a table you already have. It was linked from the Discord tab alone to begin with, on the reasoning that a feature pointed at from every screen reads as nagging — which was the wrong rule borrowed from the right place: that one is about the import nagging from campaign screens, not about the guide declining to tell anybody its own page exists. Listed tenth in a list of ten is not discoverable.
An invite is a link now
The way into a campaign has always been a URL — nobody was ever shown one. A GM copied an eight-character code, explained where to type it, and whoever received it confirmed they would join a campaign the screen would not name. All three of those are gone.
- ChangedInvites on a campaign’s members page are links you copy, not codes you read out. The button says Make a link, the link is shown in full so you can check which campaign and which domain it is before pasting it somewhere thirty people can see, and Copy is next to it. Every link still has its short code underneath, small — that is what you read aloud when somebody cannot click the thing you sent, and it is what /join still takes. An invite that has expired or been used up shows no link and no copy button at all, only the code struck through and why it died: offering to copy a URL that is going to refuse whoever clicks it moves the mistake to somebody who cannot see the screen it was made on.
- NewAn invite link says which campaign it is for before you accept it. It used to say “You’ve been invited” and nothing more, because a campaign is hidden from everyone who is not in it — the page genuinely could not find out. That was fine while an invite was a code somebody told you about; a link arrives in a chat window with no context attached, sometimes forwarded twice, and “confirm that you will join the unnamed thing behind this URL” is not a question worth asking. The name is all that is disclosed, and only to somebody holding a valid code.
- NewA link that has stopped working now says so on its own page, instead of after the click. Expired, used up, or for a campaign you are already in — each is its own screen, and the last one walks you to the campaign rather than telling you off. A suspended account is told it is the account and not the invite, which matters because the other version of that message sends somebody off to ask for a second link that will not work either.
- FixedPasting a whole invite link into the join field works. It stripped every character that was not a letter or a digit, so a pasted URL arrived as one long run of nonsense and came back “that invite code is not valid” — a correct link, refused, with an error blaming the code inside it. Now the field takes either, and says so.
Campaign settings, in five screens instead of one
Everything a GM can change about a campaign lived in one column: twelve boxes, from renaming it to deleting it, in a single scroll with no order anybody could hold in their head. It is five tabs now, grouped by what you came in to do.
- ChangedA campaign’s settings are five tabs rather than one long page. What the campaign is, its boards, its players, its world, and bringing one over from Discord — and each screen now loads only what it needs, where before every visit read the calendar, the homebrew, the eras, the page templates and the billing status even if you had come to add a board. The tabs are grouped by what you arrived meaning to do rather than by how the site stores it, which is why “a world anyone can read” sits with the campaign’s name and not with finding players: publishing a wiki and recruiting strangers were next to each other on the old page and are not the same decision.
- ChangedDeleting a campaign is at the bottom of its own screen, under a rule and a gap. It was the twelfth box on a page whose first box renamed the campaign, which is exactly the pairing that settings were split up to stop. It did not get a tab of its own: a tab marked Danger is one somebody opens out of curiosity, and this is the single screen on the site nobody should reach by browsing.
- ChangedThe Discord import is a tab, not a footnote. It was three lines of link at box ten of twelve — the newest thing a campaign can do here, filed below the sixth form nobody scrolled to. It is one of the five tabs now, and a board with nothing on it says so too: an empty board is the moment somebody thinks “there are three years of this already, somewhere else”, so it is the one other place the import is mentioned. Only those two. A feature pointed at from every screen reads as nagging rather than offering.
- ChangedThe settings tabs say which one you are on, and they fit a phone. Five labels in one row want more width than a 360-pixel screen has once the page’s own margins are taken off, and being over by anything is not a squeeze — it is a page that slides sideways under your thumb, which is the bug the top bar shipped a fix for the day before. They wrap onto a second line rather than scrolling off the edge, so nothing is hidden past a boundary with no scrollbar on it, and the tab you are reading is marked in accent and weight the way a campaign’s own sections now are.
Bringing a campaign here from Discord
A group that has been playing on Discord for three years arrives with its history in the wrong building. This is the way to bring it: a bot that reads a channel back out, a look at what that would cost before anything is written, a screen for saying who each voice in it is here, and then the import itself — threads and posts, on their original dates, attributed to the people who wrote them.
- NewA campaign can be linked to a Discord server, and a channel on it can be scanned before anything is imported. The scan writes nothing — it reads the channel and tells you what importing it would cost: how many messages, how many attachments and how much they weigh. That is deliberately a separate step from the import, because the number people are surprised by is the attachments, and finding that out afterwards is finding it out too late.
- NewImported posts keep their authors. The scan collects every distinct voice in the channel, including the ones that are not people: 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. Each voice is asked one question, and which question depends on what it is — an ordinary account is pointed at a member of the campaign, and a name a proxy bot wrote under is pointed at a character, which carries those posts to whoever plays it, because a character has an owner. Anybody at the table who has signed in here with Discord is filled in before the screen is drawn, and a character whose name matches is offered rather than assumed. Every voice can also be left unclaimed, which is the ordinary case rather than an error: 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 and marked as a voice from there rather than drawn as a member of the campaign. Somebody who asks to have their name taken off keeps the posts and loses the name, and those read as written by someone from Discord rather than by anybody.
- NewSomeone whose Discord name was copied here without being asked can have it taken off. The import stores the display name and avatar of everybody who ever wrote in the channel, most of whom never agreed to anything, so there is now a route for them: write in, and the name, the Discord id and the avatar go while the writing stays, attributed to nobody. The posts stay because an imported scene is a conversation, and deleting one voice from it leaves the others answering somebody who is not there — but if the writing should go too, that can be asked for and done.
- NewThe import itself: press a button and watch a Discord channel become threads and posts on a board. Every thread on Discord becomes a thread here, dated when it was written rather than today, so three years of history sorts into the board’s past instead of piling up at the top as though it all happened this afternoon. Consecutive messages from one person, sent within a few minutes of each other, are put back together into the post they were split out of — Discord cuts a message at two thousand characters, so one written paragraph is routinely three messages, and an archive of three-line fragments is not the archive anybody wrote.
- NewThe files come across with the writing. 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. Images and documents — PNG, JPEG, WebP and GIF, and PDF, plain text and Markdown, up to 10 MB each — are copied into the campaign’s own private storage, readable by the people at that table and nobody else. Video, audio, archives and anything larger stay on Discord, and the post says so by name: a file that was left behind is visible rather than quietly missing, which is the same line every attachment used to get. Both privacy notices changed before any of this ran, not after, because the bot’s own notice promises that they will.
- ChangedPremium campaigns hold 25 GB rather than 10, and storage now counts what an import brought over. That ceiling has never bound anybody: nobody fills 10 GB by hand a map at a time, and the first thing that ever could is five years of somebody else’s channel arriving at once. So it moves on the day the thing that fills it ships, rather than being discovered by whoever imports first. Free campaigns keep 500 MB, and an import that reaches the end of it does not stop — it keeps 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.
- NewAn import that is interrupted carries on by itself. It runs a batch at a time while you watch, so a channel with twenty thousand messages in it is not one request that has to survive twenty thousand messages — and if you close the tab, put the laptop to sleep, or lose the connection, it picks itself up within about five minutes and finishes without you. Running it again after it has finished brings over whatever has been written on Discord since and rewrites nothing: each message is remembered by its own Discord id, so nothing can arrive twice however many times it is asked for.
- NewThe bot answers for itself. Typing /hearthhall in a server it has been added to replies, where the whole channel can see it, with a link to the campaign that server is linked to — or with what this site is and how a game master links one, when nobody has. The reply says nothing the link does not: installing the bot is the act that connects a server to a campaign, and the link opens for members of that campaign and tells everybody else there is no such campaign, exactly as it would if they had guessed the address.
- ChangedBoth privacy notices say what an import copies and what happens when somebody objects. The site notice gained a section on writing brought here from Discord, and the bot’s own notice sets out what it reads, what it cannot reach, how long each part is kept, and the two remedies. They also say the one thing kept when a name is removed: a scrambled, one-way fingerprint of the Discord id, which the id cannot be read back out of and which is a different value in every campaign, kept so that importing the same channel a second time cannot quietly put the name back.
- FixedEvery scan waiting to be brought over has its own button. Only the newest one did, so a game master who scanned three channels — the ordinary way to move a server, one channel at a time — could import one of them and had no control of any kind on the other two. They sat in the list with a status and no way ever to be started. The button is now on the scan it belongs to, and several channels can be brought over in whatever order suits, in one sitting or across several. Two scans of the same channel are still offered one at a time, which is what the old rule was actually written for: two progress bars both labelled #general is a screen nobody can read, and two different channels is not that.
- FixedA scan that is waiting for you now says so. The list showed the word the database keeps, so a scan that had been mapped and was waiting to be imported announced itself as “mapping” — which reads as work in progress, and was read that way: it was waited on for an hour while it was waiting back. Each scan now says whose turn it is in as many words, and the two that are your turn are the two that stand out.
- FixedThe list of scans no longer stops at five. Scanning a server channel by channel passed that on the fourth scan, and what dropped off the bottom were the oldest scans, which are the ones most likely to have been sitting unimported. Fifty are listed now, and if there are more than that the list says so instead of quietly ending.
A top bar that fits the screen
The row of controls at the top of every page ran about sixteen pixels wider than a phone, so the whole document slid sideways and your own avatar was cut in half by the edge of the display. It fits now, and the buttons in it look like one set rather than five.
- FixedThe top bar no longer runs off the side of a phone. Six controls sat in a row built for the widest of them, and two — notifications and the theme switch — were using a button style meant for a button with a word in it, which padded a 20-pixel icon out to 56 pixels. That was the sixteen pixels the row was over by, and being over by anything is not a squeeze: it is a horizontal scrollbar on every page in the site, and the whole page sliding under your thumb as you read.
- ChangedThe buttons up there are one size and one shape now. Search, notifications, the ⋯ menu and your avatar were built three different ways and came out 44, 56, 44 and 44 pixels wide, two of them drawing a border the others did not — which is why the row looked assembled rather than designed. They are all the same square now, and the border those two were drawing was not intended: a rule near the top of the stylesheet was quietly overriding the transparent one the button style asks for.
- ChangedThe search and notification icons are drawn rather than typed. The bell was an emoji, so a phone rendered it in full colour at whatever weight the vendor font chose — a bright yellow bell in a row of grey hairlines, the loudest thing in a bar where nothing was meant to shout. Search was the opposite: a character most fonts draw at half the weight of the ⋯ beside it, so the control people reach for first read as a smudge. Both are now part of the same line-art set the rest of the site already uses.
- ChangedThe theme switch moved into the ⋯ menu on a phone, and stays in the row on anything wider. Seven controls at the size a finger needs do not fit across a phone, so one had to go, and this is the one whose job is not the page you are looking at — everything else there acts on where you are, while the theme is a choice you make about once. It is one tap further away and reachable signed in or out.
- FixedThe top bar no longer scrolls sideways on a tablet either. Reference, Characters, Premium and the moderation link all appeared at 640 pixels, where they have never fitted alongside everything else — measured on an 768-pixel screen the row wanted 764 pixels of the 720 it had. The casualty was the search box, which did not overflow but silently shrank to nothing: a field you could tab into, that screen readers announced, and that was zero pixels wide. Those four links now appear when there is room for them, and every one of them is in a menu until then.
- FixedThe wordmark sits beside the logo instead of underneath it. On a desktop the two had been stacking into a two-line brand in a one-line bar, because the rule giving that link its size on a touchscreen was also the only thing making it a row, and it does not apply to a mouse.
Finding your way around on a phone
A campaign has up to seventeen sections and a phone could see about three of them. They collapse into one list you can read now, every screen says which section you are in, and the buttons are big enough to hit.
- FixedThe buttons on a phone are big enough to press. Forty-two of them across the site were not — around sixteen pixels tall, a third of the size a finger needs — because the touch-target work done earlier only reached buttons written a particular way, and these were not. They are not obscure ones: four are in the tracker on a character sheet, three in the spellbook, two beside the ability scores. “Clear all” sat next to a plus button at half its height on the same sheet, in the same panel, during the same fight. Every button and every expander now clears the full size on a touchscreen, and none of them changed on a computer.
- ChangedA campaign’s sections collapse into a single list on a narrow screen. There are up to seventeen of them and they sat in one row that scrolled sideways, which put about three on a phone with nothing to suggest the other fourteen were there — no fade at the edge, and no scrollbar at all on an iPhone. Tapping the section you are in now opens all of them at once, grouped as the campaign, the world, play, and people. Nothing was removed to make this fit, and nothing on a desktop moved.
- NewEvery screen now says which section you are looking at. Nothing on this site had ever marked that — not the campaign tabs and not the header — which was survivable on a desktop where the page heading tells you, and was not on a phone showing three tabs out of seventeen with none of them highlighted. A wiki article keeps the Wiki tab lit rather than clearing it, so the mark follows the section rather than the page.
- FixedThe ⋯ menu no longer opens off the side of the screen. On a phone its left edge sat fifteen pixels past the edge of the display, so the first sliver of every line in it was cut off. There was already a guard meant to prevent exactly this and it could not work: it limited how wide the panel could be, when the problem was where the panel was anchored. The cause is worth saying out loud — making the buttons beside it big enough to press is what pushed it over the edge, so one fix on this list created the bug that another one on this list removes.
- FixedThe reference library can be reached from a phone. The only link to it in the site’s furniture is hidden on a narrow screen to keep the header from overflowing, and it was in neither the ⋯ menu nor the footer — so unless you arrived from the guide or a spell page, a phone had no way to it at all, despite it being the one part of this site that never needed an account. It is in both now.
- FixedThe tab you are on scrolls itself into view. On a screen wide enough for the row but too narrow for all of it, opening Moderation showed a row starting at Overview with the tab you had asked for off the right edge.
Borders worth drawing
A border can be renamed, recoloured and redirected after it is drawn, neighbours share an exact edge, and a map of a dozen territories now reads like a political map instead of a faint wash.
- NewA border can be edited. Its name, its colour, the nation that holds it, the wiki page it points at and whether players can see it are all changeable now — where before every one of them was fixed at the moment you drew the shape, and fixing a typo meant deleting the border and tracing the whole coastline again. Lines and pins can be renamed and re-pointed the same way, for the same reason: a map where the kingdom can be renamed and the road through it cannot is a map with a bug in it.
- NewCorners lock onto a border you draw near, and a stretch shared with a neighbour is traced for you. Drop a corner on one side of an existing nation and another further along it, and the coast between them is copied from that nation exactly — so the two territories share one edge rather than each having their own, and there is no sliver of nobody’s land down the seam. Hold Alt for a corner placed precisely where you clicked, or turn snapping off entirely for an island that should not touch anything. It is free, and it applies to lines too, so a road meets a frontier at the crossing rather than beside it.
- ChangedBorders are filled solidly enough to read as territory. The fill was faint enough that a map of a dozen nations read as a wash rather than as a political map, and this reaches every border already drawn as well as every new one — the same thing that happened when borders became curves. Nothing about any stored shape changed; this is how they are drawn.
- ChangedA border’s name is sized from the size of the border. A large nation is named in large letters and a small province in small ones, without anybody choosing that, which is what makes a map with twenty names on it legible rather than a wall of identical labels. The names are drawn in white with a dark outline instead of on a little panel, because a name on a map sits on the picture rather than on the page — and the picture does not change colour when you switch the site to its light theme.
- ChangedA small border drawn inside a large one now sits on top of it rather than under it. Everything was painted in whatever order it came back in, so a nation drawn after its own provinces hid every one of them; they are painted largest first now, which needs no setting and cannot be set wrong.
- NewPremium campaigns can give a border an outline colour different from its fill, make that outline thinner, heavier or absent entirely, choose exactly how solid the fill is, and make a name larger or smaller than its area would earn it — for the capital that would otherwise vanish. A heavier line is how a contested frontier reads differently from a coastline, which colour alone could not say. The better default reaches everybody, paid or not; what is paid is choosing something other than it. Renaming stays free for every campaign, including one whose subscription has lapsed, and a campaign that styled its borders while subscribed keeps every one of those choices.
A language your world speaks
A Tongues tab: pick a set of sounds and generate names that fit — for towns, rivers, people — and keep the ones you like in a dictionary.
- NewA campaign can now forge a tongue. Pick one of six sound-sets — Flowing, Harsh, Stone, Sibilant, Clipped, Vast — and its page generates six words at a time that actually sound like the same invented language, rather than six unrelated fantasy names. Reroll for six more; the address of the page changes with it, so a batch you like can be sent to somebody else or found again with the browser’s own Back button.
- NewA dictionary sits under every tongue. Anyone actually playing in the campaign — not only the GM — can coin a word — a spelling, what it means, and a note — and it stays there for the table to reuse, rather than living in one player’s head or a river name pasted into a wiki page with no way to tell whether Kethran and Kethral were meant to be related. An observer, who follows a campaign without playing in it, reads the dictionary like everyone else and does not add to it.
- NewA free campaign keeps one tongue, with a dictionary of up to fifty words, for good — the cap only stops a second one, and nothing already coined is ever taken away. Premium lifts both ceilings.
- NewA place, a faction, a map and a character can now be named from one of a campaign’s tongues instead of typed by hand — six candidates rolled from the campaign’s own sound-set, reroll for six more, and the one you pick is coined into the dictionary by default, so the name still means something the next time anybody looks it up. Hitting a free tongue’s fifty-word ceiling never stops the naming itself — only the bonus of remembering it.
- NewA tongue’s dictionary can be taken out of the site — downloaded as CSV or JSON, or sent to Handouts as a table, ready for the GM to reveal to the party whenever they choose.
- NewThe wiki can link to a coined word. Writing [[kath]] on a page where no page of that name exists now finds the dictionary entry instead of going red, and hovering it shows what the word means and which tongue it belongs to. A wiki page always wins that contest — a tongue coining a word somebody already wrote a page about changes nothing about the links already written — and the dictionary entry says so on its own line, with the address that does reach it.
- NewSearch now finds tongues and the words in them. Searching for a meaning finds the word: type “river” and the coinage for it comes back, which is the direction anybody holding a dictionary is actually searching in. Searching the coined word itself finds it too, and Tongues and Words are their own filters beside Wiki pages and Nations.
- NewA tongue can now be spoken. Type an English sentence on a tongue’s page and it comes back said in that tongue — and underneath it, every word the tongue had to invent to say it, each one click from being kept. That list is the point: translating a sentence is the fastest way anyone has found to fill a dictionary. An invented word is not a guess and not a throw of the dice either — the tongue derives it from its own seed, so “mountain” is the same word in every sentence you ever translate, whether or not anybody remembers to keep it.
- NewA GM can give a tongue its own sounds, rather than one of the six sets it was forged from. Its consonants, its vowels, what a syllable may end with, the shapes a syllable takes, how long a word runs and the clusters the language refuses — each sound weighted, so that k can be three times as common as z. The panel opens on the sound-set the tongue already has, so it starts from a real language and not a blank page, and six words are shown beside the form and rewritten as you edit: a weight you nudge shows you what that weight did. Giving a tongue its own sounds is part of Premium, and a campaign that already has one keeps editing it whatever happens to its subscription.
- NewAnd its own spelling. Every sound the tongue can make gets a box saying how it is written, so the same language is Kathris or Qathrys depending on nothing but that — two campaigns whose tongues sound alike need not look alike on the page. Sounds are spelled one at a time rather than by find-and-replace, which is what keeps a rule for th from quietly rewriting every t beside an h. Leave a box empty and the sound is written as it is said. Six words are shown spelled and unspelled together, so the choice is legible as a choice. Spelling a tongue your own way is part of Premium.
- NewA GM can shape a tongue’s grammar: where the verb goes in a sentence, what marks a plural or a possessive and which end of the word it goes on, what “the” becomes, and a short list of small words — and, not, with — that always come out the same way. The translator applies all of it. Shaping a grammar is part of Premium; a tongue without one still speaks, in English’s own order, and a campaign that already shaped one keeps editing it whatever happens to its subscription.
- NewA tongue can have a daughter. Give a parent a short list of sound changes — p becomes f, f becomes h, a vowel drops when it falls between two others — and the site derives a second language from it, carrying the whole dictionary across and ageing every word on the way. The rules run in the order you wrote them, each over what the one before it left, which is how a language actually changes: p → f and then f → h carries a p all the way to h, where the other order stops it at f. As you type them, six of the parent’s own words are shown beside what they are about to become, so a rule is something you can look at before you commit to it. Deriving a tongue is part of Premium.
- NewA daughter says where it came from, and so does its parent. Each page names the other and lists the changes that separate them, in order — so two languages that rhyme can be told apart from two that were named carelessly, which is the whole thing a pasted-in name never could. Where the rules run two of the parent’s words together, the daughter keeps one word and notes the meaning that lost beside it, because running words together is the most ordinary thing a sound change does. A daughter also invents new words the way its parent would have and then ages them, so a word it was never taught is still its parent’s word, three hundred years on.
- NewA tongue can be spoken in a scene, and only some people can follow it. Pick a tongue in the reply box and what gets posted is the translation — what you typed is kept back, and only the readers a GM has said understand that language are shown what it meant. Everybody else sees the line as it was said and a note naming the tongue, which is the honest thing: they can tell that something was said and not what. A notification about such a line carries the line, never the meaning.
- NewA GM decides who understands what, from the Members page. A tongue can be given to a person or to one of their characters and taken back again — a character carries it to whatever table that character is played at, and a person carries it themselves, which is how a campaign with nobody playing anybody does it. Nobody can give themselves a language, and nothing written on a character sheet grants one: a sheet is yours to fill in, so a language you could add there would not have been a secret in the first place.
- ChangedTwo things follow from a spoken line being stored as it was said rather than as it was meant, and both are on purpose. Search finds the words the tongue made, not the English behind them. And deleting a tongue takes every line spoken in it with it — the confirmation says so out loud rather than refusing, because the alternative is a language a campaign can never remove.
Choosing a character instead of typing one
A date of birth, which was not a thing you could give a character at all, and four more fields that were a text box and are now a list.
- NewA character can be born on a date. Pick the year, the month and the day, and if your campaign has named its months in its calendar settings the picker offers those names rather than numbers — so a D&D character is born on 14 Hearthfall, 1482 and not on 14/3/1482. Any part can be left out: a year on its own is a perfectly good answer, and so is a birthday with no year. The sheet shows it as one line in your world’s own words.
- ChangedExpertise is now ticked from the eighteen skills instead of typed into a comma-separated box, which is what the two fields directly above it already did. This one mattered more than it looks: a misspelling there parsed to nothing, so the sheet read correctly and every roll of that skill came out two to six low — on exactly the skills a rogue exists to be good at. The skills you are already proficient in are marked, because that is the thing you are looking at when you choose.
- ChangedPronouns on a freeform character, and a role and a biome on a Minecraft one, are chosen from a list with room to type anything the list has missed. The Minecraft dimension has gained the same escape hatch, so a modded server can say Twilight Forest. None of these were wrong as text boxes — they were just four members of the same town spelling “redstone engineer” four ways.
A worldbuilding campaign has nobody in it to play
The one kind of campaign that says nobody is playing anybody was offering to let you post as somebody.
- FixedA worldbuilding campaign was offering a reply in character, with a turn-order tracker above the box, dice below it, and every character you own anywhere waiting in the dropdown — including ones from other people’s tables. That is the single mode that describes itself as having no characters, so none of it belonged there. It has gone: you post as yourself, and the tracker, the dice and the character picker have left with it. Found and reported by a tester, who was right to think it looked wrong.
- ChangedA worldbuilding campaign has a tab for its boards again, called Boards rather than Roleplay. It always had two of them — Proposals and Discussion, made for it on the day it was created — but the tab had been hidden, so the only ways in were the campaign home page, the search box, or a link somebody sent you. Hiding the door to a room people were already standing in is what produced the problem above, and a board for arguing about a border is worth a way in of its own.
- ChangedNone of this is permanent and nothing is deleted by it. A campaign that changes what kind it is under Settings finds every scene, every roll and every encounter exactly where it left them — a game that becomes a world keeps everything it played, and can write in character again the moment it says it has characters.
Analytics for admins
- NewThe admin panel now says what the money is doing, whether anybody is playing, and where people fall out — subscribers and cancellations pending, contributions per day, campaigns that have gone quiet, accounts that never wrote anything. It can be downloaded as JSON or CSV. Like the usage figures it sits beside, none of it names a campaign or a person: it is counts and nothing else, so an exported file carries no personal data at all. Every download is recorded in the same log that already carries every role change and suspension.
Two-factor authentication
An optional second step when you sign in, for accounts where a password on its own is not enough.
- NewYou can now protect your account with an authenticator app. Turn it on under Settings → Security and signing in asks for a six-digit code as well as your password, so somebody who learns your password still cannot reach your campaigns — however they learned it. It is off by default and nothing changes for anybody who leaves it that way.
- NewSetting it up gives you ten recovery codes for the day the phone goes in a river. Each one gets you back in, and using one turns two-factor off rather than standing in for it — only your authenticator can prove it is you, so the honest thing is to let you back in and ask you to set it up again on a new device. Save them somewhere that is not the phone.
- ChangedThe code is asked for however you sign in, including with Google or Discord, and before you can choose a new password from a reset link. Both of those matter more than they sound: a second factor that signing in with Google walks around is not protecting anything, and one that anybody holding your email can remove is just your mailbox with extra steps.
The free member limit is eight
- ChangedA free campaign holds eight members rather than twelve. Twelve was chosen before anybody had used the site and bound nobody — a limit that never applies is not a generous one, it is an absent one. Eight still clears a GM and seven players with room to spare, and Premium raises it to a hundred for the rosters that genuinely need one. Nothing is taken from anybody: a campaign already over the line keeps every member it has, exactly as it did when these limits arrived, and is simply not offered a new place until one is free. The other two limits — two campaigns you own, 500 MB of maps and handouts — are unchanged.
Premium says what it is for, where you would want it
Five things Premium pays for were all defined on one settings page, and were therefore invisible everywhere anybody would have wanted them.
- NewTyping an invented class or ancestry into the Custom box on a character sheet now says, once, that a campaign can define it for everybody instead. That is the exact problem homebrew was built for and the exact moment it bites — four players at one table typing the same invented ancestry and spelling it three ways. Shown only to somebody who runs a campaign, because a subscription lifts the campaigns you own and telling a player to buy one would be advice that changes nothing for them.
- NewThe timeline says, under the date boxes, that a world can name its own months and ages. The site renders “Month 2” and means it, which is an odd thing for a worldbuilding site to say and a better argument than a pricing page could make. Only while a campaign has named neither: one that already has is being told nothing it does not know.
- NewThe wiki’s template row shows that the six built-in templates are not the whole list, and a map’s layer panel says what a layer is instead of offering a button that would be refused. The layer switches themselves are untouched — reading a layered map was never editing it, and a campaign whose subscription lapsed goes on seeing and toggling every layer it made.
- ChangedThe plans page stops comparing the two plans by size. It led with campaigns, members and megabytes, which made the difference between free and paid a question of how big your table is — and measured against how this site is actually used, that is a difference nobody here has ever felt. Both columns now lead with what you can do and end with one line of limits.
- FixedAdmitting somebody by handle to a campaign that is already full said “They could not be added. Try again.” — an instruction to repeat something that cannot work until a place is freed. It now says the campaign is full, what the limit is, and that removing somebody frees a place. The applications queue had already been fixed; this was the other way in.
- FixedThe hint under a timeline event’s date boxes claimed no world here has a named calendar yet. Calendars shipped two days ago, so a campaign that had named eighteen months was being told none existed.
Dice, on the tab called Dice
The Dice tab was a record of rolls and not a place to make one. Rolling anything meant opening a scene.
- NewA roll box at the top of a campaign’s Dice tab. For when you want a number rather than a scene — checking what a modifier actually comes to, settling something that came up in chat, rolling for weather before writing the post. Nothing has to be open and nobody has to be posting.
- ChangedA roll made there counts. It belongs to the campaign, lands in the log directly beneath it and is added into the totals and the per-face figures, exactly as a roll made in play is — server-thrown, and undeletable by anybody including the GM and site staff. The alternative was a scratchpad whose results never appeared in the log under it, which is a page that argues with itself: you roll a d20 on a campaign’s own Dice tab and the campaign tells you nothing has ever been rolled there. It would also have been the one place on this site you could roll for a campaign without the campaign knowing.
- ChangedA roll in a scene still names the scene and links to it; a roll made on the tab says “not in a scene” instead. Rolls made from a character sheet with nothing in play are unchanged — they belong to no campaign, are counted nowhere, and remain yours.
- FixedA roll that belongs to no scene used to be readable by any account on the site. That was survivable while such a roll belonged to no campaign and was shown to nobody but the person who made it, and it would have stopped being survivable the moment one carried a campaign — every campaign here is private, and which campaigns exist is private too. A roll on a campaign’s tab is now that campaign’s members; a roll off your own sheet is now yours alone. The second half of that was already worth fixing: a sheet roll carries a label like “Stealth” or “Death save”, and those had been readable by strangers since long before this.
- ChangedThe guide said the Dice tab is not a roll box. It says where the box is instead, and what a roll made there means.
A border that is saved looks saved
Two complaints about drawing on a map, which turned out to be one thing wrong twice over.
- FixedSaving a border left the line you traced sitting on top of it, in the drawing colour, with its handles still attached — so a finished border looked like an unfinished one wearing a second copy of itself. The border was always saved correctly; the editor simply never let go of the shape after the server took it, and nothing but Cancel had ever cleared it.
- FixedReshaping a border or a line appeared to do nothing until the page was reloaded. The same cause: while a shape is being reshaped the map hides the committed version, so the old outline does not sit underneath the new one arguing with it — and since the editor never came out of reshaping, the shape stayed hidden behind the drawing that had already been saved. The redrawn shape had been stored and sent back the whole time; it was covered up.
- ChangedSaving a border now leaves the tool open with the map clear, because the thing people do after drawing one nation is drawing the one beside it. Finishing a reshape closes the tool instead — that job has an end, and there is no next shape to carry on with.
- FixedA reshape the database refuses now says so. It used to be written and never checked, which meant a refused redraw and a successful one looked identical: the editor closed, the page redrew, and the old shape came back with no explanation. That is indistinguishable from the bug above, and it would have been the cheap thing to be wrong about twice.
Somewhere for the testers to look
- NewPeople given tester access have a page of their own listing what the current round is asking them to check, with their own share of it first. It is reached from the account menu and nobody else can see it. Tester access itself is unchanged — it is still a grant an admin hands out, not a role, so somebody can be a tester and a moderator at once.
A campaign you can post in
A new campaign arrives with boards, and asks for the one thing it still needs.
- FixedA new campaign had no boards, and a scene has to live in one — so a campaign nobody had set up by hand could not be posted in at all, and said the boards were waiting for a first scene. Campaigns now start with two, chosen by what kind of campaign it is, and every existing campaign that had none has been given them.
- NewA campaign that has not started yet asks its GM for the two things it needs — a first scene and a second person — and stops asking once it has both.
- NewThat checklist can now be dismissed. A campaign with people who simply never post there — a world built in the wiki and the maps, say — was stuck seeing it forever; any admin can now close it for good.
- ChangedInvite codes moved from settings to the members page, next to adding somebody by handle. Settings is for changing how a campaign works; wanting another person in it is not that.
A border’s name lands inside the border
- FixedA border shaped like an L, a crescent, or a ring around a lake could put its own name outside itself. The label sat at the shape’s average position, and for anything with a notch or a bite taken out of it, that average can fall in the missing part rather than in the shape — an L’s label landing in the empty rectangle at its own crook. The label now finds the point furthest from every edge instead, which cannot land outside a shape that has an inside.
- FixedWhile a border was being drawn or reshaped, its draggable corners could sit directly on top of another border’s name, painted over the text with nothing to explain it. Every border label is now hidden for the few seconds a shape is actively being drawn, and all of them come back the moment you finish.
- FixedA long border name could run past the edges of its own shape in both directions, since the label never wrapped. Names now wrap onto a second line within a fixed width and stay centred, rather than spilling out to either side.
A base is in the country it looks like it is in
- FixedA player’s home shown on a map was matched against a border’s corners rather than against the border you can actually see. Borders are drawn as curves through their corners, and a curve bows outside the straight lines between them — so somewhere in that bulge was ground that plainly sat inside a nation and was reported as belonging to none. On a border with only a few corners the gap reached five per cent of the map’s width. The label now reads the same shape that is drawn, so what it says and what you can see cannot disagree.
The legal pages say more, and one of them said something untrue
A pass over the terms, the privacy notice and the content policy for European law. Mostly additions — and one correction that mattered.
- FixedThe terms said that when you subscribe you are asked at checkout to agree that Premium should start immediately, and to acknowledge that this ends your fourteen-day right to withdraw. Nothing at checkout asked you anything. That right is only given up if you actually consent and actually acknowledge it, so the paragraph described a step that never happened. Checkout now genuinely asks: there is a box to tick before the payment can go through, the terms it points at say plainly what ticking it means, and the acceptance is recorded.
- NewThe privacy notice names the data protection authority you can complain to, with its address — the Czech one, since that is where this is run from — and says that if you live elsewhere in the EEA you can complain to your own instead. It said only “your national data protection authority”, which left you to find out which that was and how to reach it.
- NewThe terms and the content policy now say what happens when something is reported and when something is removed. What a report should contain, that a person reads it, that you are told what was removed and on what basis, and that you can ask for a second look or go to a court instead. None of this changes how reports are handled — it writes down what already happens, which is what the Digital Services Act asks a service hosting other people’s writing to do.
- NewThe pages that identify who runs this now carry the trade register number as well as the name and address, which an online service in the EU is required to publish.
- ChangedNothing above changes what is collected, what it is used for, or who sees it. No new tracking, no new sharing, and no new rules about what you may post.
Premium for people testing it
- NewA site admin can give an account Premium without a payment, for people asked to go and break a paid feature before it ships. It is the real thing rather than a badge: the account ceilings lift, and campaigns they own get layers, map lines, calendars, homebrew and page templates, because that is where nearly all of the paid surface actually lives.
- NewOnly an admin can give one, and that is enforced by the database rather than by the page — twice. The policy refuses anyone without the role, and a trigger refuses even the key this site uses for the jobs that bypass its own permissions, which is the only way to say “only an admin” and mean it. Every grant and revocation lands in the same moderation log a suspension does.
- ChangedSomebody given it is told so. Their billing page says Premium as a tester, with the reason the admin wrote, rather than showing a subscription with no card attached and no renewal date — which is what it would otherwise have looked like, and reads as either a fault or a bill you cannot find.
Easier to hit, easier to find
An accessibility pass. Nothing about how the site looks changed; a good deal about whether you can actually use it did, particularly with a thumb.
- FixedButtons, menu rows, icons and links are big enough to hit with a thumb. On a 375-pixel screen, thirty-four of the front page’s controls were smaller than the size a finger needs; none are now. Nothing changed on a computer — a mouse is precise, this site is dense with tables and character sheets, and making every button a third taller for everybody would have made those worse to fix a problem a mouse does not have.
- FixedThe header, the footer and the links at the bottom of each landing section were the worst of it. A row in the header’s menu was thirty-two pixels tall, the footer’s links sixteen, and the icons beside the theme toggle were smaller than they looked. All of them now clear the full target size on a touchscreen and are unchanged on a desktop.
- FixedLinks and focus outlines on the parchment theme are legible. Amber on parchment sat at about 2.4 to 1 against the 4.5 to 1 that text that size needs — a known trade for the warmth of the colour, written down at the time and now no longer necessary. Link text is a deeper amber; the buttons are the exact colour they always were, which is what having two values for the accent was always for.
- ChangedBoxes you type into have a clearer edge, and a focused one keeps it. The border used to be the same near-invisible hairline that separates two panels, so a form was something you found by guessing; focusing a field then removed it entirely, which on a short input read as the field disappearing rather than being selected.
- NewA link to Hearthhall pasted into Discord, Slack or a message now unfurls into a proper card — the mark, the name, what the site is for and what you get — instead of the grey box it drew before. There was no preview image and nothing telling a chat client how to render the link, which mattered more than it sounds: a private hall is shared in exactly one place, and it is a chat window.
- ChangedThe front page says what this site is for, in the right order: campaigns first, the worlds behind them second, Minecraft third. Worldbuilding was missing from that sentence entirely — as were maps and timelines, which is most of what it means here — so the description a stranger reads covered the wiki and the dice and nothing about drawing a border or dating an event.
- ChangedA new typeface for the interface. It carries proper column-aligned numerals, which this site needed and did not have: ability scores, hit points, dice results and storage bars all shifted by a pixel as their value changed. Posts and wiki pages are untouched — they are still set in the reading serif they have always used.
- ChangedExplanatory text under a field or a heading is a size larger. It was 12.5 pixels, which is below where being technically legible stops being the same thing as being readable, and it is the size of nearly every hint on the site.
A map you can draw on, and turn things off
Two things could go on a map: a pin, and a closed shape clicked corner by corner. That is the right pair for a town and a kingdom, and no use at all for a road.
- NewLines. An open one, two points or five hundred, which is the thing a polygon could never be — a road, a river, a coastline, or the arrow somebody draws mid-session to show where the party went. They carry a colour, a weight and a link to a wiki page, the same as a border does, and the weight is a fraction of the map rather than a number of pixels, so a road on a map shown small is drawn thin rather than three times too heavy.
- NewLayers. Everything placed on a map used to land in one flat pile — forty pins, the borders, the trade routes and whatever was marked during session twelve, all on at once. Now they can be grouped and switched on and off while reading. A layer is a reader’s switch and not a permission: whether a player may see a thing is still answered by the thing’s own visibility, and marking a layer off by default hides it from nobody who could not already see it.
- NewDeleting a layer frees what was on it rather than taking it along. The pins, borders and lines fall back to the base layer and stay exactly where they were drawn — the same choice deleting a season already made about its world. There is no undo on a map, and somebody tidying a list of layers has not asked to lose a year of cartography.
- ChangedLayers and lines are the first thing on this site that Premium pays for, and the shape of that is worth saying plainly. A campaign that stops subscribing keeps every layer and every line it ever drew, keeps seeing them, and can still rename, move and delete them. It simply cannot add another until it subscribes again. Pins and borders are untouched by any of this and remain free, as they always were — nothing that worked yesterday costs money today.
A failed payment is a card to fix, not a subscription to buy again
A review before launch found four ways the billing side could tell somebody the wrong thing about money. None of them needed anything unusual to happen — a declined renewal, a card that never cleared, a closed account.
- FixedWhen a renewal payment is declined, Premium stops but the subscription does not — and the page was still offering Subscribe, which would have started a second subscription beside the first and billed for both once the original recovered. Subscribe now appears only when there is genuinely nothing to manage, and a declined payment says where the card gets changed instead.
- FixedAn account whose first payment never completed could not be deleted. Closing it tries to stop the subscription first, deliberately, so nobody is billed for an account they closed — but a subscription that never started is one Stripe will not cancel, and the attempt failed in a way that refused the deletion and pointed at a billing portal with nothing in it.
- FixedCancelling and re-subscribing shortly afterwards could drop Premium again until the next renewal, if the old subscription’s last message arrived after the new one had been recorded.
- FixedDeleting a map or a handout now deletes its file too, so it gives the campaign its room back. It always only removed the row, which meant a campaign’s storage could only ever go up — while the message shown when you ran out of room suggested deleting a map to make some, which did nothing at all.
- FixedAdmitting somebody into a campaign that is already full now says so, and says that Premium raises the limit. It used to do nothing whatever: the button worked, the application stayed where it was, and neither the applicant nor the GM was told why.
- FixedA character who plays in more than one campaign keeps the links in their bio. Those links are recorded once per campaign the character has appeared in, and the rule meant to stop the same link being recorded twice did not know about campaigns — so for anyone with one character in two games, saving their bio quietly removed every link instead of rewriting it, and the Characters section of every wiki page’s backlinks was empty for exactly the people the feature was built for.
- ChangedOwnership of a campaign is now something only an owner can hand out or take away. A co-GM can still admit people, excuse them, and move anyone between the other roles — that is the job — but the top rung is what deleting a campaign, publishing its world and advertising it all hang from, and it was not one a co-GM should be able to award themselves. Publishing a campaign’s world to the open internet is owner-only for the same reason, which the settings page has always implied and the database now agrees with.
- FixedEditing a war no longer removes its entries from a published timeline. The “begins” and “ends” entries are rebuilt from the war whenever it changes, and the rebuild forgot that they had been published — so correcting a typo in the outcome months later quietly shortened the public history, with nothing to connect the two.
- FixedA published map draws the pins and borders that point at published wiki pages. It was looking those up among the world’s places instead, which is a different list of names entirely, so almost everything annotated was dropped from the public map and the occasional coincidence linked to the wrong thing.
- ChangedA suspended account can no longer join a campaign by invite code, which the other two ways in already refused, and can no longer define a campaign’s calendar, ages, page templates or homebrew. Removing what is already there still works — a suspension should not leave somebody unable to tidy up after themselves.
- FixedA page turned GM-only stops telling the players who were watching it. Watches were checked when they were made and never again, so everyone following a page kept being sent its title and the GM’s edit comment after it was hidden — and could not stop it, because unwatching a page you can no longer see was refused too. Both halves are fixed: GM-only edits reach only the people who run the campaign, and a watch can always be dropped.
- FixedA short rest no longer removes temporary hit points. They last until they are used up or until a long rest, which matters most for the class that rests short in the first place — a warlock recovering their slots was quietly losing the hit points from Armor of Agathys at the same time.
- FixedExpertise survives importing a sheet. The importer could already tell a skill with expertise from a merely proficient one — it reads the printed total — and then had nowhere to record it, so the roll button offered a number two to six too low on exactly the skills a rogue is built around. Sheets now have an Expertise field, and both the PDF and JSON importers fill it in.
- FixedExported PDFs keep their paragraphs and their names. Anything the sheet’s font could not draw was deleted rather than simplified, so a multi-paragraph features box came out as one unbroken line and a name with Czech or Polish letters printed with holes in it. Accents are now folded to plain letters, which is what the rest of the site already does with them.
- FixedEditing a war can no longer leave it with no sides at all. Replacing the list was two separate steps, so a failure between them removed every participant and reported success anyway; it is now one, and a failure leaves the record exactly as it was.
- FixedSaving something you are no longer allowed to edit says so instead of saying “Saved.” — the case being a tab left open while your role in the campaign changed. Leaving a campaign you are the only owner of explains why it will not let you, rather than sending you to the home page as though it had worked.
- FixedDeclining an application that another GM has just accepted no longer goes through, and no longer emails a new member to say they were turned down. Withdrawing one that was already decided is refused for the same reason.
- ChangedAn observer can no longer roll dice into a scene. The role is described as reading everything and writing nothing, and the dice log is a permanent record of a scene like any post in it.
- FixedA campaign’s own subclasses and heritages can now be picked, not only defined. They are offered under whichever class or ancestry is chosen, and the picker only appeared for one of ours — so a subclass invented under an invented class could be created and never used. Making a new character also offers your campaigns’ homebrew now, which is the moment it is most needed and the one place it was missing.
- FixedSuspending an account no longer does the opposite when the days box is empty or has a word in it. Which of the two buttons was pressed is now what decides, rather than the number being unreadable.
- FixedA name or a command inside a code block no longer becomes a link, and no longer notifies whoever happens to own that handle. Wiki pages quoting a server command were pinging real people about a conversation they were not in.
- FixedExpertise, ability scores and dice all read a little more carefully. A sheet printing a dump stat beside its modifier now keeps the odd number rather than rounding it away, and 4d6Kh3 is accepted as readily as 4d6kh3 was.
- FixedReverting a wiki page respects the lock, and refuses when somebody edited the page while you were reading its history — where before it would quietly discard their edit. Renaming a map layer says when it did not take.
- FixedPaging back through a long notification list no longer skips entries. Several notifications from one campaign-wide announcement share the same instant, and the “Older” link could not tell them apart.
- ChangedDice rolled as part of a post count against the same per-minute limit as every other roll, and a session can no longer be confirmed for a time belonging to a different session or for a date that does not exist.
- ChangedMember profiles now require an account to read, which is what the rest of the site has assumed since campaigns became private. Your display name, handle, bio and join date were readable by anyone without signing in — a leftover from before this site had groups at all. A character you publish is unaffected: that is a separate address you opt into per character, and it stays open to everybody.
- ChangedThe reason given for a suspension is now readable only by site staff and by the person it is about. It used to sit on the profile itself, which meant anybody with an account could read what a moderator had written about somebody else. That a suspension exists is still visible — it always was — but the note explaining it is not.
Codes at checkout
- NewPremium checkout now takes a discount code. If you have been given one, carry on to the payment page and there is a box for it — the price updates before you agree to anything, and whatever the code is worth is what you pay.
Borders you draw rather than assemble
A border used to be built one clicked corner at a time, which made every coastline a polygon and made a phone a bad place to draw one. Now you trace it.
- ChangedDrag across the map to trace a border and the line follows your finger or your mouse, the way drawing anything else does. Zoom in first and the stroke keeps more detail, because at six times in you are being six times more careful about the terrain underneath. A stroke adds to the shape rather than replacing it, so a coastline longer than the screen is traced in pieces: draw what you can see, move the map, carry on. Clicking still drops a single corner, for an edge that really is straight.
- FixedPinching to zoom while drawing on a phone left a stray corner behind wherever your second finger happened to be. Every zoom put a spike in the shape you were drawing, which is the main reason hand-drawn borders came out looking like nothing anybody drew. A gesture with two fingers in it is now a gesture with two fingers in it, and drops nothing.
- ChangedTwo fingers now move the map as well as zoom it, at any point — necessary while drawing, where one finger is the pen, and an improvement everywhere else. On a computer, dragging with the right mouse button moves the map while a border is being drawn.
- ChangedBorders are drawn as curves rather than as straight lines between their corners. Nothing about a saved border changed; this is how they are drawn. Every border already on a map is drawn the new way too, so a coast traced with forty corners reads as a coast instead of as a fence around one.
- NewUndo stroke takes back the last thing you drew rather than the whole shape, which one bad stroke used to cost. A traced shape also hides its corner handles by default, since a dot on each of forty corners covers the border it belongs to; a checkbox brings them back for nudging one.
- FixedA border with more corners than can be stored used to be cut off after the first two hundred and saved anyway — keeping an inch of the north shore and closing the shape straight back across the country, with no error to say so. It is now thinned evenly along its whole length instead, in the browser and on the server alike, so the shape that is saved is the shape you were looking at.
Pages your world starts from, and ages it counts in
A wiki page has always started from one of six templates, and a timeline event’s era has always been whatever you typed. Both are the right defaults for most campaigns and the wrong ones for a table whose world has a shape of its own — its own kind of page, its own named ages.
- NewA campaign can define its own wiki page templates, offered in New Page beside the six built-in ones. A custom template is not a thinner version of the built-ins sitting in the same list — it carries the same infobox fields, the same tags and the same seeded body, so a page for a ship, a noble house or a god’s domain starts as shaped as a character sheet already does.
- NewA campaign can name its ages. The free-text box on a timeline event’s era already took anything you typed; now it also offers what your world has named, so “Second Age”, “2nd Age” and “TA” can be one age instead of three. Typing something nobody defined still works exactly as it always did — the box stays free text, not a dropdown that only takes what is on the list.
- ChangedNeither is a reference. A template is copied into the page the moment it is used, and an era is copied into the event’s era field, the same as if you had typed either by hand — so removing a template changes no page it ever started, and removing an age changes no date on any event that used it. There was never a link to break.
- NewDefining either is Premium; a page that starts from one, and an event that names one, are not, and will not be. A campaign that already has templates or named ages keeps all of them, keeps offering them, and can still remove one if a subscription lapses — only adding another is refused.
Where a link takes you after signing in
A security fix. The pages that send you somewhere once you have signed in, confirmed an address or set a new password checked that the destination was on this site — and the check was wrong in a way that let a crafted link send you off it.
- FixedA link could carry a destination that looked like a path on this site and was not, and browsers would follow it away to somebody else’s. The place that mattered was the link in a password-reset email: it arrives trusted, and the redirect happened at the moment the reset was accepted, which is when a convincing copy of the sign-in page would do the most damage. Nothing was reachable through it — no account, no campaign, no data — but it was a way to hand somebody a phishing page with our flow behind it.
- ChangedThe check now resolves the destination the way a browser does and keeps it only if it stayed on this site, rather than trying to recognise the ways it might not have. There were three copies of it and all three were wrong together, so there is now one, with a test that keeps it honest.
- FixedReading your own subscription is now asked for by name rather than left to the database to narrow. It always returned the right row for everybody except a site administrator, for whom it could return somebody else’s — enough, on the billing page, to open the wrong person’s Stripe portal.
Homebrew the table can pick
Every list on a character sheet has a Custom box, and what you type into it belongs to that one character. So four people at one table using the same invented ancestry typed it four times and spelled it three ways.
- NewA campaign can define its own classes, subclasses, ancestries, heritages, backgrounds and alignments, and they appear in everybody’s picker — in their own group, under the official list and above Custom, so “is this ours or is this the book’s” is answerable at a glance. A subclass or a heritage can be hung under whichever class or ancestry it belongs to, ours or yours, and only shows up once that is what the character has chosen.
- NewThe same name cannot be added twice to one list however it is capitalised, which is the entire point rather than a nicety — Tidewalker and tideWALKER being two ancestries is the exact thing this feature exists to stop.
- ChangedA character who already had one of these typed into the Custom box now shows it as a proper choice instead, without anything being rewritten: the sheet has always stored these as plain text, so a campaign’s list changes what is offered and nothing about what is kept. That is also why removing an entry cannot break a character — it goes back to being what somebody typed, which is what it always was.
- NewThese carry no rules. No hit die, no proficiencies, no ability bonuses, nothing that reaches the arithmetic — what a number means is a separate thing being built, and half a class stored here would only have to be unpicked when the real version arrives. What this buys is agreement about spelling, which was the thing actually going wrong.
- NewDefining the shared list is Premium; the Custom box on every picker is not, and will not be. A campaign that has invented some keeps them, keeps them in the picker, and can still rename and remove them if the subscription ends — only adding another is refused.
Month 2, day 14
A timeline event has always carried a month and a day, and never had anywhere to look up what either of them is called. So the interface said month 2, and meant it.
- NewA campaign can name its months. Eighteen of them, of forty days each, or twelve, or three — the order is the numbering, so the second month you list is the one an event stored as month 2, and dates start reading the way your world writes them. Weekdays too, if a world has bothered to name those. Nothing about how a date is stored changed, and nothing already written moved.
- NewA published world shows the calendar its history is written in. Without that a stranger reading your timeline would see “month 2” on the same page a member reads “Frostwane” — not a leak, but the kind of disagreement only the people who already know the answer are able to notice.
- ChangedA campaign that has not named its months reads exactly as it did before, character for character. That is the point of the fallback rather than an accident of it: a month number the calendar cannot reach — a world that shortened its year after somebody had already recorded month 14 — falls back to the number rather than being rounded into a month it did not happen in. Wrong and looking right is worse than clumsy and honest.
- NewNaming your months is Premium, and it takes the shape every paid thing here takes: a campaign that defines a calendar keeps it, keeps seeing it, and can still rename a month, add one or throw the whole thing away if the subscription ends. Only defining a first calendar is refused. Timeline events, and every date already written in them, were never part of the plan and are not now.
A paid plan, and the first ceilings this site has had
Hearthhall has been free and unmetered since it started, which is a pleasant thing to say and not a thing one person can keep saying forever. This is the attempt to make it pay for itself without taking anything away from anybody.
- NewPremium, at €5.99 a month. It belongs to a person rather than to a campaign, and it lifts the ceilings on every campaign that person owns — so a GM running three tables pays once, and the people they play with never pay at all and never need a different kind of account.
- NewThe free plan now has ceilings, which it never did before: two campaigns owned, twelve members in each, and 500 MB of maps and handouts per campaign. Premium raises those to unlimited campaigns, a hundred members and 10 GB. Twelve was chosen because it covers a GM, five or six players and a couple of people watching; a hundred is for the Minecraft servers and the West Marches games, which are a different shape of thing rather than a bigger version of the same one.
- NewGoing over a ceiling stops a campaign growing and does nothing else. Every member, map, page and word stays exactly where it is, still readable, still exportable — a campaign simply cannot take a new one until it is back under the limit or subscribed. That applies the same way to a campaign that was already over a ceiling on the day these arrived and to one whose subscription lapses later, and it is enforced by the shape of the check rather than by anybody remembering: the rule can only refuse things being added, so there is no code path by which it could remove something.
- NewStorage counts the maps and handouts a campaign holds, and nothing else. Avatars and character portraits live in a place that is organised by who uploaded them rather than by which campaign they were for, so there is no campaign to charge them to — said here and on both new pages, because a storage figure that quietly means something narrower than a reader assumes is a promise that breaks the first time somebody adds it up.
- NewTwo pages: /premium, which says what the plan lifts today and separately lists the four things it is being built to pay for, marked as not existing yet; and a Premium tab in settings showing what each campaign you own is actually using, read from the same figures the upload check consults rather than from a number typed into the page.
- NewThree, counting the one nobody here renders. Stripe’s checkout page now lists what the plan includes and marks each thing it does not, because Stripe draws an identical tick beside every row and a caveat sitting in a heading would not have survived the journey — so every unbuilt item carries its own. The list is set by the script that creates the product rather than typed into a dashboard, and a re-run corrects an old one, which is what stops checkout offering to build something on the day after it shipped.
- ChangedThe terms no longer say the site is provided free of charge, and the liability paragraph that was built on that sentence has been rewritten. Paying for something changes what a person is owed, and the page that describes what they are owed should not have to be read around.
- NewCancelling, changing a card, and finding an invoice all happen at Stripe rather than here. That is partly because they do it better in more languages, and partly because it keeps a useful property: nothing on this site can write down that somebody has paid. Only the message Stripe sends can, and it is refused unless it carries a signature proving it came from them.
- NewStripe is the seller, not us. Premium is sold through Stripe as merchant of record, which means the receipt names them, and calculating and paying VAT wherever you happen to live is their job rather than something a site run by one person in the Czech Republic has to get right in twenty-seven tax regimes. It is the difference between this being possible to offer and it not being — and it is on the terms page rather than buried here, because who you are buying from is a thing you should be able to find out before you buy.
The sheet, on the phone you actually brought
A character sheet is used sitting at a table, and the thing most people have on the table is a phone. The sheet was laid out for a desk and stacked in whatever order the desk had put things in.
- ChangedOn a narrow screen the sheet is ordered by how often you touch a thing rather than by which column it sat in on a wide one. The tracker comes first — conditions, spell slots, resources, everything that changes during play — then attacks, then the roll buttons, then the spellbook and the dice. The written-down parts of the character, the campaign list and the export come after them. Before this the tracker was last, underneath the whole sheet and the spellbook, so the control you reach for every few minutes in a fight was the one furthest from your thumb.
- ChangedNothing moved on a desk. The two columns are unchanged above the point where they stop fitting, and the reordering is done in the layout rather than by rendering the sheet twice and hiding one of them — so there is still one set of controls, one of each field, and a screen reader is not offered the whole page a second time. Printing a sheet is unchanged too.
- ChangedThe buttons you tap during a session are big enough to tap. The plus and minus on spell slots, resources and inventory, and the condition toggles beside them, were about 26 pixels tall — fine under a mouse, a coin toss under a thumb, and the cost of missing is a spell slot spent that was not meant to be. They grow on touchscreens only, so no toolbar on a desktop moves and a tablet gets the larger target even though its screen is wide.
- FixedThe five coin boxes in the purse no longer squeeze into a row too narrow to read a four-figure pile of copper in. Three across on a phone, five once there is room.
- ChangedThe roadmap has been rewritten and now sorts by what a stretch of work is for rather than by how likely it is to happen. Five bands: making what is here good enough to keep using, making a campaign easier to run, making this somewhere you can find a table rather than only host one, worldbuilding that knows what it is describing, and an honest bucket for what is wanted and unscheduled. The old three said only how confident anybody was, which put a calendar next to a magic item next to a notification system and read as one person’s inbox.
- FixedIt had two things on it that were already built — the published world, which shipped last week, and the stalled-scene notice, whose own entry above quotes the roadmap item it was finishing. A roadmap listing finished work is worse than a short one, because it is the page somebody reads to find out what is missing.
- ChangedGetting a phone right is now the first thing on it. Territory changing hands has moved the other way, from near the top to the world-engine band: it was high on the strength of how good it would be, and the campaigns here draw almost no borders and have declared no wars at all. Leading a roadmap with a feature built on the two least used things on the site is how a small site talks itself into building for nobody.
- ChangedOne band on it is about features that already exist. The campaign directory, the looking-for-a-game notices and the published worlds are all finished, all working and all very nearly empty, and the useful thing to write down about them is not another way to advertise a campaign but that the ones built have not been found yet. Saying so on the public page seemed better than quietly deleting the entry.
Which of this gets used
A page for whoever runs the server, about what has been built and what has been opened.
- NewWhoever runs the site can see which features campaigns actually use — how many games have ever made a map, written a session, drawn a border or filled in a sheet, and how many did so recently. It is counted from the things themselves rather than from a record of anybody’s comings and goings: no log of who did what was added, and none is planned, because everything on the page was already sitting in the rows each feature stores.
- NewIt counts campaigns rather than entries, which is the whole point of it. One table that loves heraldry can write four hundred entries about its noble houses, and that says nothing about whether anybody else has ever opened the same screen.
- ChangedNothing on that page names a campaign or a person, and it cannot: it is counts and nothing else. Being an admin still does not open a game — the wiki, the boards, the maps and the handouts are each shut to everybody who is not a member, and that has not moved.
The map, for people who are not in the campaign
- NewA map can be published like anything else, and what is drawn on it comes too — the pins and the borders, without needing to be published one at a time. A map hidden from your players stays hidden from everybody, and so does any pin or border marked the same way.
- NewA pin pointing at somewhere you have not published does not appear at all, rather than appearing without its link. A pin is nearly always labelled with the name of the place it points to, so leaving it there unlinked would hand over the very thing withholding the link was meant to keep.
- ChangedThe picture itself is served from an address that does not change, so a browser can cache it and a search engine can find it. What it is not is a key to the file: the store the maps live in stays shut, exactly as shut as it was yesterday, and this site fetches the image for you only after checking the map was published. Nothing about who uploaded it leaves — which is the reason the store stayed shut rather than being opened for published maps, since it knows that and the map’s address does not.
- ChangedUnpublishing a map takes it off the page at once and stops the picture being fetchable within a minute. That minute is real and worth knowing about: a copy already in somebody’s browser is theirs, and a map that has been public cannot be made unseen — the same thing the privacy policy has always said about a published character.
A world, not only its articles
- NewThe rest of the world can be published, not only the wiki: places, the powers that hold them, the wars and treaties between them, and the history. Each is its own switch and each starts off, the same as an article, and the campaign switch still has to be on before any of it is readable by anybody.
- NewA published thing never names an unpublished one. A town belonging to a duchy you have not published shows no duchy at all — not the name without a link, which is the whole of what a reader would have learned from the link anyway. The same goes for a power’s overlord, the sides in a war, and any article one of them points at. A war fought against a power nobody was told about reads as a war with fewer sides, which is the honest way for it to come out.
- NewIt is the query that decides that, not the page. There are eight public pages now and there will be more, and a rule that each one has to remember is a rule that gets forgotten once and stays forgotten.
- ChangedPublishing any of it is a decision for the people running the campaign, enforced by the database rather than by which buttons are on screen. Every one of these things is editable by everybody in the campaign, which is the point of a shared world — and it is exactly why the switch that makes something public could not be left as an ordinary field on the row.
A world you can show people
Everything here has been invisible outside its campaign, which is right for a D&D table and wrong for a server whose nations ought to be readable by anyone thinking of joining.
- NewA campaign can publish individual wiki pages to an address anyone can read, with no account and no invitation. It is two switches and both start off: one for the campaign, one for each page. Nothing becomes readable because somebody forgot about it — a page is public only if it was marked, in a campaign that was separately opened.
- NewA published world lives at its own address rather than at the campaign’s. That is not tidiness. Which campaigns exist here is private and always has been: a campaign you are not in answers “no such group” rather than “not allowed”, so that a stranger cannot learn what exists by knocking. Serving public pages from the same addresses would have made that answer conditional, and a crawler could then have mapped every campaign on the site by reading response codes.
- NewThe campaign switch closes everything at once without forgetting anything. A GM who publishes and thinks better of it turns one control off; every page keeps the choice that was made for it, and turning the switch back on restores exactly what was there rather than a blank slate.
- ChangedA published page links only to other published pages. Inside a campaign an unwritten page renders as a red link, which is an invitation to write it. On a public page that would be an announcement — it would tell a stranger that a page exists, what it is called, and offer an address that answers “sign in” and then “no such page”. So a link to anything unpublished renders as the words that were in it, and a name mentioned in a page is text rather than a link to somebody’s profile.
- ChangedA published page says what was written and not who wrote it. The authorship a campaign keeps for its own history — who created a page, who last edited it, what they said about the edit — does not leave the campaign, and the query that serves public pages cannot return it even by accident, because it names every column it sends.
- FixedPublishing is a decision only the people running a campaign can make. A wiki is editable by everybody in it, which is the point of a wiki — and for one migration that meant the publish setting was editable by everybody too, not through any button but by asking the database directly. It is now refused for anyone but an owner or a moderator, and a page hidden from players is un-published by the database rather than merely ignored by the pages that serve it. Found by the test written alongside the feature rather than by anybody reading it.
Asking the same question twenty times
- FixedEvery page you opened asked the login server who you were, over the network, once for the page and once again for every link on it. Opening a board with twenty scenes on it could ask twenty-one times. The site now checks your session against a signing key it already holds, on the machine serving the page, which is the same proof of identity with none of the waiting — so pages come back sooner, and the part of this site most likely to fall over under load stopped being asked to.
- ChangedOnly your account’s identifier is read from the session token. Anything that can change — whether you are staff, whether you are banned — is still read from the database on every request, because a token says what was true when it was issued and those are exactly the facts that must not be stale. The rules in the database were never involved in this and have not moved.
The scene that stopped three weeks ago
The front page has always been good at what is waiting on you and silent about what is waiting on somebody else. Waiting is how play by post dies, and it is now visible to everybody who could end it.
- NewA campaign shows which of its open scenes have stopped, who each one is waiting on, and how long it has been. It sits under “Waiting on you” on the campaign overview and as a marker on every board listing. The database has been able to answer this for a long time — whose turn it is has been stored since the initiative tracker landed, and who has written in a scene since the very first migration — but the only place either was visible was inside the thread, which is exactly where somebody who has stopped opening the thread will not look.
- NewIt is shown to everyone in the campaign rather than to the GM alone. That was a real choice and the other one was defensible: the roadmap framed this as something for “the one person who can end it”. But a GM who has to chase four players is still doing four chases, and the person holding a scene up is the person who can unblock it without anybody being nagged. Nothing on it is new information — the initiative order and the post list are already on screen for every member — it is those facts gathered into one place.
- NewA scene that has gone quiet says which kind of quiet it is. Somebody’s turn in an initiative order is a fact and is named as one, down to which combatant they are holding up. Somebody who wrote in the scene and has not written since the last post is an inference, and is worded as one. And a thread nobody but its author ever answered is a third thing entirely — it does not need chasing, it needs recruiting or closing, and telling a GM it was “waiting on nobody” would have been true and useless.
- ChangedA scene waits on somebody who has not written, not on somebody who has not looked. The quick way to build this was to invert the list that tells you what is waiting on you, and two of that list’s three signals are other people’s read state. Reading them would have turned “whether someone else has read a thread is not your business” — a decision this site made in its fifth migration and has kept since — into read receipts under a name nobody would recognise as the thing that was refused. Nothing here consults them, and the definition that avoided them is the better one anyway: a post is a contribution, and opening a page is not. Writing “sorry all, busy week” out of character counts, because saying you are still here is the thing that stops a table assuming otherwise.
- FixedThe setup reference had stopped listing migrations at 0041, and two applied since — the email digest and the migration that withdrew it — had never been written down. A table of what has been applied to a database is worth exactly as much as its most recent honest line, and adding this release’s migration on top of that gap would have hidden it rather than closed it.
Reporting the scene, not a line of it
- NewA Report control at the foot of every thread. The moderation queue has had a Thread label since the first migration and nothing on any page could produce one — filing a thread report meant posting the form by hand — so the content policy told you to report the post a thread opens with and explain in the reason that you meant the whole thing. That aimed the complaint at the wrong object twice over: the opening post is often the one part of a derailed scene that was fine, and the answer to a bad thread is to lock it, which is not the answer to a bad post. It also collided with itself, because the queue allows one open report per person per thing: reporting the opening post for what the opening post said used up the only slot you had for reporting the thread.
- ChangedThe thread control is shown to the thread’s own author, which is where it parts company with the Report link under each post. That link is hidden from the person who wrote the post, because reporting yourself is nothing anybody needs. A scene is not the same: unless you are a group admin you cannot lock a thread you started, and asking for one that has gone somewhere bad to be locked is the reason the control exists.
- ChangedThe content policy and section 7 of the terms count threads among the things the Report control appears on, and the sentence sending you to the opening post is gone with it. It was honest advice about a missing control, and the day the control arrives it becomes an instruction to use the wrong one.
Documents that had stopped describing the site
The terms describe a site with four features, written when that was true. Since then this place learned to hold pictures, to publish a character, to list a campaign and to delete one — and none of the three documents anybody is asked to agree to had heard about any of it.
- ChangedThe terms say what the site is now: maps, a timeline, handouts and a schedule alongside the wiki, the boards, the sheets and the dice. The old sentence stopped at four of those, and a description that is two thirds of the truth is the wrong thing to have at the top of an agreement — it is the section everything below it is scoped by.
- NewA section on what other people can see, because “a campaign is visible only to its members” had quietly acquired four exceptions and named none of them. A listed campaign, a published character, a notice on the player board, and your profile. Three of those are switches somebody presses; the fourth comes with having an account, and it is the one worth saying out loud.
- NewPublishing is written into the licence rather than assumed by it. The licence granted to us was to show your writing to the other members of your campaign, which is exactly what a published character page does not do — so the one feature that makes something world-readable was the one the licence did not cover. It now says so, says it is limited to what you published, and says the honest part too: a page that has been public cannot be un-read.
- NewDeleting a campaign is in the terms, on the day the button arrives. What goes, what does not — nobody’s characters — that a moderator is not offered it, and that there is no undo and no asking for one.
- NewA section for the spell list and the bestiary, which are neither yours nor ours: the SRD under Creative Commons Attribution, passed on under a licence we hold on the same terms you do rather than granted by us. The credit is the one condition, and it is why the line sits at the foot of every page that shows any of it.
- NewA copyright complaint has an address and a shape. There was a Report control on four kinds of thing and no document that mentioned it existed, and a rights holder arriving here found a rule against posting other people’s work and no way to say that somebody had. Neither the terms nor the content policy could tell you where to write.
- NewThe content policy covers pictures, which it never has. The first rule now names an uploaded and a generated image as plainly as a written one, and two things about uploading are stated rather than left to be discovered: a map or a handout is checked against membership, and everything else sits at an address that cannot be guessed and is not a password. Somebody choosing what to put in a campaign is entitled to know which of those they are using.
- NewA section on the pages strangers can read. The rules do not change there; who is standing there when one is broken does. Three things that are your own business inside a campaign are not on a page anyone can open: contact details, passing yourself off as a real person or as one of us, and advertising.
- ChangedReporting says to use the Report control, which the page had never mentioned — it told you to write to a mailbox instead, for a thing that already had a button carrying the address of what it points at. The mailbox is still the answer for the first list and for anything the campaign’s own moderators are in.
- ChangedThe content policy carries a date. It forms part of the terms and had been the one document here with no way of telling whether it had moved — which is the wrong page to have to guess about, since it is also the one most likely to change.
- FixedThe privacy policy said your username and display name were shown to other members of your groups. Your profile page is readable by anyone holding its address, account or no account, and carries your avatar and your bio as well. Crawlers are told to stay away from it, which keeps it out of search results and is not the same as keeping it private — and the difference is exactly the sort of thing somebody should not have to read robots.txt to learn.
- NewThe privacy policy admits the one thing that does reach another site. An avatar can be a link rather than an upload, and where it is, your browser fetches it from whoever hosts it and that host sees the request — under a heading that until now said nothing follows you anywhere. Proxying every such picture through this site would hide you from that host by handing us a log of every image every member looks at, which is the worse trade and is why it is not done.
- ChangedThe subprocessor list stopped claiming the mail provider sends notifications. It sends two things: a confirmation and a password reset. The digest was scrapped before it ever sent a message, and a list of who handles your data is worth exactly as much as its least accurate line.
Ending a campaign
- NewAn owner can delete their campaign. The database has said they may since the very first migration — owner or site admin, the same rule that already deletes a campaign when its only owner deletes their account — but nothing on any page ever asked, so a GM with a false start had to either write to an admin or keep it in their list forever. It sits at the foot of campaign settings, behind the campaign’s own name typed out in full, and a moderator is not shown it: running a campaign and ending one are not the same job. It takes the boards, the wiki and its history, the timeline, the maps, the handouts and the sessions. It does not take anybody’s characters — those belong to their players, and only their place on the roster goes.
- FixedDeleting a campaign now deletes its map and handout images too, and deleting your account deletes your avatar and your character portraits. Every one of those was a file rather than a row, and no amount of cascading in the database reaches a file — so until now the pages went and the pictures stayed, indefinitely, for a campaign that no longer existed. The maps and handouts were the ones that mattered: those are the large ones, and they are the ones a GM deletes a campaign to be rid of.
- ChangedThe privacy policy says what happens to an uploaded picture, which it had never covered. Two things are now written down rather than merely true. A picture you put into a campaign that outlives your account stays, on exactly the reasoning the policy already gave for keeping your posts — it is part of somebody else’s scene, and removing it tears the same hole. And an uploaded picture lives at an address that is unguessable but not secret, so sharing the address shares the picture; that has been true since the day uploads were added, and it is a strange thing to have found out by reading the source. Maps and handouts have never been in that storage, and the policy now says so in the same breath.
A front door, a reference, and three features nobody could use
One day of work, and most of it turned out to be repairs. The landing page and the pages it links to were rebuilt — and along the way the spell list was found to be hiding two thirds of itself, a wiki article to be rendering in the sidebar gutter, and the sessions page never to have worked at all.
- FixedEvery page in the application scrolled sideways on a phone once you were signed in. The header was carrying 355px of content in the 343px a 375px screen has — a wordmark, a group switcher, search, notifications, a menu, a theme toggle and an avatar — and twelve pixels over is not a squeeze but a horizontal scrollbar on every screen, with the whole document sliding under your thumb and the logo cut off at the left edge. The wordmark now drops to the mark alone once you are signed in, and the group switcher keeps its unread dot and loses its label. Signed out both stay, because that row is four things and has the room, and it is the state a stranger arrives in.
- NewA second seed script, `npm run seed:campaign`, builds a campaign meant to actually be played by testers rather than looked at: an episodic garrison game with no fixed party, three opening threads at three different levels of commitment, revealed handouts, a session with times to vote on, and an invite code. It found the sessions bug within a minute of running.
- NewWiki bodies and in-character posts are set in Literata — a serif drawn for long reading on screen, whose slight slab reads as a printed rulebook rather than a magazine. It appears nowhere else: not on the landing page, not in a button, not in the guide. A warm ground with a serif headline is the most worn look on the web, and inverting it is the point — the serif here is not decoration, it is the signal that you are reading something a person you play with typed. Dice expressions inside a post stay in the mono, because that is the mechanics talking and not the author.
- NewA seed script, `npm run seed:demo`, builds one campaign with enough in it to look at — a wiki whose pages link to a page nobody has written, a thread that reads like play, and characters with filled sheets. Every empty state on this site had been designed against an empty database, which is the one case where the empty state is not the interesting one; the wiki column bug above had been shipped for weeks and was found within a minute of there being a page with a body in it. It writes no accounts, is owned by whoever runs it, and `--remove` takes it away again.
- NewA campaign’s overview says what the campaign wants from you. It listed what had happened — five recent pages, five recent threads — and nothing about which of it was addressed to the person reading. Whose turn it is, who named you, and which scenes have moved now sit above both lists, from the same query the site’s front page has used for months, so whose-turn logic lives in one place rather than two that will disagree.
- NewA campaign’s tabs are grouped. There were up to seventeen in one scrolling row with Applications and Moderation beside Wiki as though they were the same kind of errand; there are now seams between where you are, the world you are writing, the game you are playing, and the people — with the two tabs only an owner sees at the far end, where a member’s eye never has to travel.
- NewThe page forks under the hero, because two different people arrive on it: somebody holding an invite code from a friend, and somebody who has never heard of the site. They get a door each, pointing at the two tracks the guide already had, and a line under both for the third case — no code and no table — which goes to the campaign directory.
- NewPictures, drawn rather than photographed. Seven line icons and six figures — a hall, a wiki page, a thread, a roll, a character sheet and an in-world timeline — built out of the site’s own palette and primitives instead of exported as images, so they turn over with the theme rather than being one theme’s worth of pixels, and they cannot quietly start lying the way a screenshot does the first time the interface moves.
- NewA menu in the header carrying everything the footer carries. The footer is the right place for those links and the wrong place to have to reach for them: the landing page is about five thousand pixels long now, so wanting the changelog meant scrolling deliberately to the end of a document you were not otherwise reading. Not a bar that follows you down the page, which is the other obvious answer and a worse one — a fixed strip spends vertical space on every screen, most expensively on the phone that has least to spare, to keep links permanently visible that most people want once.
- ChangedThe Delete control on a post waits until you point at it. A moderator sees one against every post in a thread, so a page whose content is somebody’s writing was carrying a column of ways to destroy that writing, and it was the loudest thing on the screen. It is still one movement away, the keyboard still reaches it by tabbing, and a touchscreen — which cannot hover and would otherwise be left with a control it can never reveal — goes on seeing it always.
- ChangedThe guide hub is built from the same bands as the landing page, and the two starting tracks — joining a game, running one — now outweigh the seven topics instead of being two more identical cards in a column of eleven. Each topic carries the same mark the landing page gives that feature, so the wiki is recognisable before the word is read. Joining and running also stopped appearing twice: the old page listed them as tracks and then again as the “start here” section, which was invisible only because every card on the page carried the same weight.
- ChangedThe changelog is drawn as a timeline, with the date on a rail of its own rather than as a grey timestamp at the end of a heading — which is the one place nobody compares anything. The marker is filled for work that has not shipped and hollow for the history. The roadmap deliberately does not get this treatment: it has no dates on purpose, because a date there would be a promise nobody made, and drawing it as a sequence would quietly invent one.
- ChangedThe campaign directory explains itself when it is empty, which on this site is the resting state rather than a failure — every campaign is private the moment it exists, and listing one is an opt-in almost nobody takes. A short directory is the privacy model working, so the page now says so and offers the next thing to do. A search that found nothing and a directory with nothing in it are different questions and get different answers.
- ChangedBoth are tables grouped by the thing you sort by: spells by level, monsters by challenge rating. Casting time, range, armour class, hit points and speed get columns of their own rather than being run together in one grey line, which is what makes four rows comparable at a glance. Sending every row also means the browser’s own find-in-page searches the entire library, which no paginated list can offer.
- ChangedColumns drop as the window narrows rather than the table scrolling sideways, and what the narrow layout loses reappears under the spell’s name. A reference you have to drag left and right to read is a worse reference, and the name — the thing being looked for — is never the column that goes over the edge.
- ChangedThe landing page is rebuilt out of full-width bands rather than a column of cards, alternating surface and canvas so there is somewhere for the eye to stop, and each of the five main features now sits beside a picture of itself with the side alternating down the page. Nothing gained a shadow: the seams are hairlines, the same weight as every other rule on the site, and no panel floats above another. The prose above the fold is about a third of what it was, and the detail it lost is in the guide, which exists for that.
- ChangedThe parchment theme is warmer and no longer has any white in it. Canvas, surface and surface-2 used to sit inside five percent of each other, which is fine when a card is the only coloured thing on a page and falls apart when the page is a stack of full-width bands — two neighbouring bands read as one flat beige with an unexplained line through it. Worse, one of those bands was the card colour, which is near-white by necessity because a card has to lift off what it sits on; painted across a whole window it stopped reading as a panel and started reading as a plain white website. Every full-width ground is now parchment, the alternating band carries a real amber cast, and near-white belongs to cards alone.
- ChangedThe amber splits in two. It was doing two jobs that pull opposite ways: as a fill it wants to be the brightest ember on the page, and as text it has to stay readable against parchment — and one value serving both is what turned the light theme’s primary button into brown mud. The fill is now a proper ember carrying dark ink rather than white, which is both truer to the palette and better contrast than what it replaced.
- ChangedBands paint their own colour rather than borrowing the nested-panel one. Those were the same value, and sharing it held the band back: surface-2 carries faint text inside every card-flat in the application, which pins how dark it can be, while a band carries nothing smaller than body copy and can go much further. Splitting them is what let the light theme get properly warm without dragging every panel in the app along behind it.
- ChangedSign-in and sign-up carry a panel beside the form. They were a single narrow card on an empty canvas, which is a hard landing from a page that has just spent five thousand pixels making an argument — the argument evaporated at exactly the moment somebody was deciding whether to act on it. Three of its claims now sit alongside the fields, and below a wide screen they sit under them, because the form is what the page is for. The four other account screens are unchanged: they ask for nothing and keep the narrow column they had.
- FixedThe sessions page asked PostgREST for a session and its proposed times in one query, and PostgREST refused it. Sessions and session slots point at each other — a slot names the session it belongs to, and a session names the slot that won — so there are two relationships between the same pair of tables and no way to guess which was meant. A refused embed comes back as an empty result rather than as an error, so the page read it as “nothing on the calendar” and said so, confidently, no matter how many sessions existed. Naming the foreign key fixes it. This is the third time this exact trap has caught something in this codebase, which is why it has its own paragraph in the contributor notes.
- FixedA wiki page with a body and headings in it was rendering the article in the 288px sidebar column while the contents list took the 784px one. The prose carried an `order-1` meant to float the infobox above it on a phone — except `order` does nothing in block layout, so it never worked there, and at the width where the grid does honour it, it sorted the article after the sidebar and handed it the gutter. Both halves are fixed: the infobox stacks above the article on a narrow screen, as the comment beside it always claimed, and the article gets the wide column.
- FixedSign-in no longer blames you for an outage. Every failure came back as “that email and password combination is not right”, which is the correct thing to tell a visitor — a precise message would let anyone test which addresses have accounts here — but it was also the only thing written down anywhere. A deployment that could not reach the auth server at all told every visitor their password was wrong. The message is unchanged; a transport failure now also says so in the server log, where only whoever runs the deployment can see it.
- FixedTwo thirds of the library was unreachable. Both lists asked for at most 80 rows against 319 spells and 325 monsters, had no pagination, and ended with a line reading “80 shown” — so the missing 239 spells were not hidden behind anything, they were simply absent, and the page did not admit it. Both now send the whole library.
- FixedThe Join button was clipped off the right edge of a phone screen when signed out. The header was carrying about 371px of content in 343px of space, so the campaign directory link now drops below the small breakpoint, as the guide and reference links already did, and the footer carries it on every page instead.
- FixedFaint text failed the contrast floor in both themes — 3.80:1 on a light card and 3.97:1 on the dark canvas, against the 4.5:1 that text of that size needs. Both shades are re-picked against the lightest surface faint text ever lands on, and the worst pairing on the site is now 4.67:1. This moves every hint, placeholder and byline in the application, not just the ones on the landing page.
- FixedSections rise slightly as they come into view, driven by a scroll timeline rather than a script, and behind both a @supports test and prefers-reduced-motion — so a browser without view timelines shows a still page rather than an empty one, and anybody who has asked their system for less movement gets no animation at all.
Somewhere that explains how any of this works
This site has had thirteen kinds of thing you can make and no page that says so. Everything was discoverable by clicking around, which works for the tabs and does not work at all for the parts that are typed rather than clicked — nobody finds double-bracket links, keep-highest dice or the second visibility switch on a character by looking harder at a screen.
- NewA guide at /guide: a hub, two starting tracks — one for somebody who has just been handed an invite code, one for somebody about to run a game — and nine topic pages covering the wiki, play-by-post, characters and sheets, dice, maps and the timeline, sessions and handouts, and the account. Readable without signing in, which is the point: the honest way to tell a stranger what this site does is to show them how it works rather than ask them to make an account and find out.
- NewThe dice page is a full reference for the expression grammar, because it was the one part of this site with a syntax and no documentation. Every form the parser accepts is on it, including the ones nobody was going to guess: d20 with the count left off, kh with the number left off, and adv as a suffix on the whole expression rather than a term of its own. The three limits it quotes are imported from the parser rather than typed out, so raising one cannot leave the page quietly wrong.
- NewEach page says plainly which campaigns it applies to. The world layer is Minecraft’s and the bestiary and party roster are D&D’s, which is a decision rather than an omission — and somebody who goes looking for a Nations tab that is not there is better served by being told why than by concluding the site is broken.
- ChangedSigned out, the guide is in the header beside the reference library, which is the only way it reaches somebody who arrived at a listed campaign from a search result rather than at the front page. Signed in it moves to the account menu, because a member has the header space spent on their own campaigns and does not need to be sold the explanation twice. The footer carries it on every page either way.
- ChangedOn the front page the link sits directly under the pitch rather than two thirds of the way down. It had been placed after the feature cards and the paragraphs about privacy, which is to say it was only ever reaching people who had already decided to keep reading — precisely the ones who did not need it. Signed in, the same link is on the empty state somebody sees the moment they have an account and no campaign, which is the exact minute the question comes up.
- ChangedThe one number the guide could not read from the code — the forty rolls a minute each person is allowed — moved out of the server action that enforces it and into the dice module beside the other three limits. A server action file may only export functions, so that constant could not be imported from anywhere; it would have had to be retyped into the guide, and a documented limit that has to be retyped to stay correct is one that eventually is not.
Search learns the rest of the site exists
Search was built when there were four things to search. There are now thirteen, and it had never looked at the other nine — so a nation, a town, a war or a handout could be typed into the box and come back with nothing.
- NewSearch now finds nations, places, wars and treaties, timeline events, maps, handouts and sessions. Each of these has existed for a while and none of them has ever been findable, which is the sort of gap nobody reports — you type the name of a town, get nothing, and quietly decide the search is bad rather than that it has never heard of towns.
- NewThe spell list and the bestiary are searchable from the same box. They rank below anything a person at your table wrote, so a search for “fire” answers with the burned-down village before it answers with forty spells — and they are left out entirely when you narrow the search to one campaign, because reference material belongs to no campaign. The filter says so on the page rather than leaving you to work it out.
- ChangedA result that is part of a longer page now scrolls to the right spot instead of dropping you at the top. Timeline events and sessions do not have pages of their own, so searching for one takes you to the timeline or the schedule and jumps to the entry that matched.
- FixedA GM-only nation, place or timeline entry stays invisible to players in search, and a handout you have written but not yet revealed does not surface its title. That was never a matter of the search remembering to check: every one of these reads the same permission rules the pages themselves use, so a rule tightened anywhere is tightened here too. There is now a test for each of them that asks the database rather than taking the arrangement on trust.
A table that was never meant to be public
One table in this database was reachable by anyone, and it was the one that records which database changes have been made. Nothing about you was in it. It is closed now, and the tool that created it no longer creates it that way.
- FixedThe list of applied database migrations could be read — and written — without signing in. It holds no account, character, campaign or message data; it is a list of filenames and the times they ran, so there was nothing in it about anybody. The write access mattered more than the read: a forged row naming a change that never ran would have made the next deployment skip that change and say it had succeeded.
- FixedThe cause was that this one table was created by the migration tool itself rather than by a migration, so it never passed through the step where every other table has its access rules turned on. Sixty-odd tables were correct and one was not, which is exactly the shape of mistake a rule applied by hand produces. The tool now locks the table in the same statement that creates it, so a fresh deployment of this site never has the gap at all — not even for the length of its first run.
Borders somebody drew
Every faction has carried a colour since the day factions existed, with nothing to paint. A map held pins and coordinates and no areas, so a nation’s territory was a sentence.
- NewTerritory can be drawn on a map. Click around the edge of a claim, drag a corner to move it, click one to remove it, and the shape is filled in whichever colour the nation that holds the ground already uses. A campaign with no nations picks a colour for the border itself — maps belong to every system even though nations do not.
- NewBorders can be reshaped after the fact without being redrawn. The corners come back as handles, and saving submits the whole shape once rather than a write per pixel — so a drag that gets abandoned halfway leaves nothing behind.
- ChangedA border’s corners are stored as fractions of the image, exactly as a pin’s position is, and for a reason that matters more here: a map re-exported at twice the resolution moves every pixel coordinate on it, and a border is forty points rather than one — forty times less obvious and forty times more annoying to put right.
- ChangedThe label sits at the polygon’s area centroid rather than the average of its corners. The average is pulled towards whichever edge was clicked most, so a coastline traced with forty points against a straight inland border of two would put the name out at sea.
- NewThe database refuses anything that is not a polygon: fewer than three corners, a corner that is not two numbers, a corner outside the image. That is a check constraint rather than a rule the interface remembers, so a shape that would draw as nonsense cannot be stored by any route into the data.
- ChangedA GM-only border is drawn dashed as well as tagged, so it reads as provisional at a glance. Players do not see it at all — it is absent from the query rather than hidden by the interface, which is how everything else here works.
- ChangedMaps say how many borders they carry alongside how many pins. The list used to say “3 pins” for a map that also held four territories, which is a summary that lies about the thing it summarises.
- NewA town inside a border says whose ground it is on. Worked out from the shape rather than written down, so redrawing a border around a town changes the answer without anybody editing the town — which is the version that survives a war. Concave territory works, and a place in the notch of a C-shaped claim is correctly outside it rather than merely inside its bounding box.
- ChangedWhere two claims overlap, a place names one of them rather than listing both. Overlapping territory is a dispute, and the honest picture of a dispute is the two shapes drawn over each other — which the map already shows — rather than a tidy list implying somebody has settled it.
- FixedZooming a map now keeps whatever is under the pointer under the pointer. It used to scale about the middle of the frame, so pointing at a city and zooming walked that city towards the edge — the further from the centre the thing you cared about was, the harder the map fought you.
- FixedA map can no longer be dragged out of its own frame. Panning hard while zoomed in used to park the image off-screen and leave a grey box with nothing to indicate anything was still there, and the only way back was the Reset button.
- FixedPinch-to-zoom works on a touchscreen. The map had to switch off the browser’s touch gestures in order to be panned at all, and that took pinch-to-zoom with it — so a phone could zoom in and then not out again except by finding the minus button. Two fingers are now handled directly, and one finger still scrolls the page past a map at rest.
- FixedThe zoom animation no longer fights the gesture. A transition was re-starting on every wheel notch and every frame of a pinch, which turned a continuous movement into a rubber band that never quite caught up. Only the buttons animate now, which is the only place a step is worth smoothing.
- FixedScrolling over a map zooms it, without having to press the plus button first. The wheel used to be ignored entirely until the map was already zoomed in, on the reasoning that a map taller than the viewport should not trap the page — which was a real problem answered in the wrong place. A control that ignores you until it has been primed reads as broken, and this one was.
- ChangedThe page stays escapable by a narrower rule: a wheel event that would not change the zoom is not the map’s. Scrolling down on a map already at rest scrolls the page, scrolling up on one already at full zoom scrolls the page, and everything in between zooms.
A line nobody was going to draw twice
Towns and builds were two tables, two tabs and two forms, separated by a distinction that falls apart the moment somebody builds a walled town nobody lives in.
- ChangedTowns and builds are one thing called Places. The rule was that a settlement is somewhere people live and a build is a project — which leaves a base, a farm with a bed in it, and half of everything anybody makes on a server sitting exactly on the line. What told them apart is now a dropdown: town, base, farm, monument, outpost, landmark.
- Changed“Ruin” stopped being a kind of place. It was a status wearing a kind’s clothes — a ruin is a thing that happened to a monument, not a category of one — so it folds into “abandoned”, which was already there and already meant it.
- ChangedWho runs a place and who built it are one field. On a server they are the same person, and asking twice got the same name typed into two boxes.
- ChangedWars carried six kinds and six stances, in a feature one day old, for a question with about three answers. Rivalry was a war nobody declared; ceasefire and trade pact were treaties with adjectives. What is left is war, treaty and alliance — and a side is an aggressor, a defender, a signatory, or nobody.
- FixedThe nether conversion appeared in three places: as a whole section on the towns list, and as a notice on every town and every build. It appears once now, on the page where you are already looking at the coordinates, which is the only moment anybody wants it.
- ChangedA Minecraft campaign is no longer offered dice, handouts or session scheduling. All three describe a table that meets on Wednesdays: a d20 expression parser, material a GM prepares and reveals, and voting on which evening everyone can make. A server is up all week and people log in when they log in.
- ChangedNothing was deleted for any of this. Every build became a place, keeping its screenshot, its coordinates and who made it, and a campaign that switches system finds its dice log and its handouts exactly where they were.
Taking back what was not worth having
The world layer went out to every campaign on the reasoning that a D&D table has factions too. It does, and that was not the point: what a campaign actually gained was four more tabs and a coordinate box for a world with no coordinates in it.
- ChangedNations, towns, wars and seasons are Minecraft only. A D&D or General campaign describes its factions the way it always did — a wiki page from the Faction template, and a pin on the map — which is one tab instead of four and was never actually the worse answer.
- FixedA D&D campaign had a coordinate box on it. Coordinates come off the F3 screen; a hand-drawn coastline has none, and the mechanism that already puts a place on a fantasy map is clicking where it goes. That box is gone, along with the nether converter that came with it.
- FixedThe nav had reached seventeen tabs and was scrolling sideways, on a site whose whole argument is that it is quieter than the alternatives. That was the symptom rather than the disease, and it has been fixed by removing four things rather than by hiding them behind a menu.
- ChangedThe same record is no longer offered under three sets of names. Calling it Nations for one system, Factions for another and Powers for a third was solving a problem created by shipping it to systems that did not want it — and "Ages" for a feature that exists because a server *resets* was the point at which the whole idea should have been reconsidered.
- FixedA nation no longer carries its own founding date. A founding is an event, events belong on the timeline, and a second private copy of when something began meant a world could say 412 in one place and 414 in another with nothing to reconcile them. The two columns are dropped rather than left unwritten, because a column nothing writes is one somebody eventually believes.
- ChangedNothing was deleted. A campaign that made a faction or a town in the last few hours still has every row of it; the interface simply stopped offering the tabs. Throwing away somebody’s writing to tidy up a nav would be the worse mistake of the two.
General stops meaning “not the other two”
General is the system for almost every game there is, and it has been carrying six fields and no tooling. It now asks what kind of campaign it is, and lets one design its own sheet.
- NewA General campaign says which of three things it is. A tabletop game has characters and rules; a worldbuilding project has a world and nobody playing anybody; a play-by-post community writes prose and has no use for statistics. All three were being handed the same near-empty sheet and the same fourteen tabs.
- ChangedA worldbuilding campaign is no longer offered roleplay boards or dice, because nobody in one is playing anybody. What it keeps is the part it came for: the wiki, the timeline, the maps, and the powers in the world. Nothing is deleted by changing mode — switch back and every tab returns with everything still in it.
- NewA campaign can design its own character sheet: name the fields, pick short text, long text, a number or a list of choices, and mark which numbers get a roll button. Those roll through the same machinery a D&D ability does, so a homebrew stat lands in the dice log looking exactly like a Stealth check — which is the entire point of describing a sheet as data.
- ChangedWhat somebody fills into a campaign’s own sheet belongs to the pair, not to the character. A character can be in three campaigns, and two of them that both invented a field called Corruption keep two separate numbers rather than quietly sharing one. It shows up on the character’s page once per campaign, and only for readers who are in that campaign.
- ChangedRenaming a field keeps everything already written in it. The key a value is filed under is generated once and never regenerated, because the alternative is a rename that silently empties every sheet in the campaign — the sort of thing that looks like it worked until somebody notices a month later.
- NewA GM can write on a campaign sheet as well as its owner. That is deliberate: a campaign-specific sheet is exactly where the curse the GM put on you goes, and a sheet only its owner can touch cannot hold that. Nothing is hidden — the whole campaign can see it.
- ChangedD&D and Minecraft keep their sheets in code and are not offered a builder. Those work out modifiers, armour class and spell slots, and rewriting them as a field list would be a rewrite of the part that already works.
The address, the rules, and the thing you built
A Minecraft campaign could describe its nations and could not say where the server was. It can now — along with the projects that are not towns.
- NewA Server tab, for Minecraft campaigns only. Where to connect, Java or Bedrock, the version, what it runs, the difficulty, the seed, whether it is whitelisted — and the rules, in Markdown, at the top of the same page. The rules and the address are the same question asked twice, and answering one here and the other three clicks away is how somebody joins and immediately breaks a rule nobody showed them.
- NewBuilds: farms, monuments, rail lines and walls, with coordinates, a screenshot, who built it, and what state it is in. Deliberately not the same thing as a town — a settlement is somewhere people live and has a steward and a population, and forcing both into one shape would mean a population column on a storage silo.
- New“Abandoned” is one of the states a build can be in, and it earns its place. Every server has a half-finished megaproject somebody stopped coming back to, and recording it as abandoned reads better a year later than deleting it or leaving it marked “building” forever.
- NewPlaced builds appear on the maps as a third kind of marker: a diamond is somebody’s base, a circle is a town, a square is a build. Shape rather than colour, so it still works for a nation that never picked one.
- ChangedWho built something is free text rather than a list of accounts. The people who built a thing include players who left, players who never made a character, and one person everybody only knows by their in-game name — a proper list of accounts would be able to record fewer of them, not more.
- FixedLinks in the server details have to start with http:// or https://, enforced by the database rather than by whichever page happens to render them. A stored “javascript:” that reached a link would be an attack that survived every reload, and the rule is in the one place that cannot be forgotten.
- ChangedThe live map is a link that opens in its own tab rather than a panel embedded in the page. This site refuses to put anything in a frame at all — that is a deliberate line, not an oversight — and a server map is the one thing that genuinely wants the whole screen anyway.
Who did what to whom
Nations could exist and could do nothing to each other. Wars and treaties are records now, with the sides named — and they put themselves on the timeline so nobody has to write the same war down twice.
- NewWars, treaties, alliances, ceasefires, trade pacts and standing rivalries, in one place, with each side named and marked as what it was. A war and a treaty look like opposites and are the same shape — a named thing between powers, with a start, an end, a standing and an outcome somebody disputes — so they are one record, and what differs is the part each faction played in it.
- NewAggressor and defender are stored as a claim rather than a fact, which is the honest way round: who started it is exactly what the losing side denies. The record holds one answer and the wiki page holds the argument, which is where an argument belongs — somewhere with revisions behind it.
- NewAnything with a year on it writes itself onto the timeline: one entry when it began, another when it ended, both rebuilt whenever the record changes and both removed with it. A war that is not on the timeline is a war somebody has to remember to write down twice, and the second time never happens.
- ChangedA GM-only war is secret all the way down. Its timeline entries carry the same restriction, because a hidden record announced by its own entry on a public timeline is not hidden — it is merely inconvenient to read.
- NewEvery faction’s page now lists what it has been through, and does not filter by season: a nation that carried a grudge across a server reset should show both halves of it.
- ChangedA treaty that expired and a treaty somebody tore up are the same row meaning different things, so “broken” is a standing of its own rather than a kind of “ended”. Which of the two it was is most of what anybody ever argues about afterwards.
- ChangedVassalage is deliberately not one of the kinds here. It is already recorded on the faction itself, because it is a standing condition rather than something with an end — and modelling it in two places is how the two come to disagree about who serves whom.
- FixedDeleting a nation no longer takes its wars with it. A war that vanishes because one side was tidied away is a hole in the history of the world; the record survives, keeps the sides that remain, and says so.
Who holds the ground
A world could be written about and not held. Nations, towns and the runs of a world are records now, and a Minecraft server stops being handed a D&D campaign with the words changed.
- NewFactions — nations, powers, whatever the table calls them — are a thing the site keeps rather than a page somebody wrote. Each one has a leader, a standing, a founding date, a colour, and a roster of the characters in it, and can answer to another. That last part is the one worth having: a vassal that says who it is a vassal of turns a list of names into a map of who owes what to whom.
- NewSettlements: towns, capitals, outposts and ruins, each belonging to a faction or to nobody. Give one coordinates — pasted straight off the F3 screen, in whatever shape it arrives — and it places itself on every map that has been told what its edges mean. That trick already existed for one player’s base on a Minecraft sheet and had no business being restricted to it.
- NewSeasons, for a world that starts over. A server resets, the map is regenerated, and every nation on it stops being true — but the writing about them does not stop being worth reading. So a season files the facts and never the prose: factions, towns, maps and events carry one, and the wiki, the boards and everybody’s characters deliberately do not. Starting a new season moves nothing and deletes nothing; it changes what the next thing you make files itself under.
- ChangedA campaign is shown the words its own system uses. The same record reads as Nations on a Minecraft server, Factions in a D&D campaign, and Powers in a group that is building a world for its own sake — and the addresses underneath never change, so a link sent last year still opens the same page. A server handed a page headed “Factions” reads it as a plugin; a table handed one headed “Nations” wonders where its thieves’ guild goes.
- ChangedTabs that had nothing behind them for a given system are gone rather than renamed. The bestiary is the SRD and the party page reads a D&D sheet, so neither is offered to a Minecraft server or a freeform group — there is nothing there for them to be renamed to. Everything genuinely shared stays shared.
- ChangedMaps draw the two registers differently. A diamond is somebody’s survival base, read off their character sheet; a circle is a settlement the whole group agreed is there, in its faction’s colour. Shape carries the difference rather than colour alone, so it survives a faction that never picked one and a reader who cannot tell them apart.
- NewNether coordinates, worked out and shown. It is a division by eight and everybody gets it wrong once by dividing the height too, which does not scale between dimensions — so the height is left exactly where it was.
- ChangedDeleting a season releases its world rather than taking it with it, and a season holding anything cannot be deleted at all. Deleting a faction frees its towns instead of destroying them. Neither touches a wiki page: prose belongs somewhere with revisions behind it, and no record here has ever been the place to keep it.
What is kept, and what is counted
The site starts counting page views, and finishes telling you what it already keeps on your device — which turned out to be twice as much as the privacy policy admitted.
- FixedThe privacy policy said two things were kept on your device, and there were four. The one it left out is the one worth telling you about: a post you have started and not sent is held in your browser for up to a fortnight, which is this site keeping something you wrote and never mentioning it. It also called the theme setting a cookie, which it has never been — it is browser storage, covered by the same rules and by a different word.
- ChangedThat section now lists all four, says which of them ever reaches a server — one does, and it is not the drafts — and explains the sweep that clears unsent writing when somebody else signs in on a shared computer, which the site has always done and never claimed credit for.
- ChangedThe reason there is still no consent banner is stated rather than assumed: consent is what the law asks for before something is placed on your device, and nothing here is on your device that you did not put there yourself.
- NewPage views are counted, which they never were before. It records the page, roughly where in the world it was asked for, and what sort of device asked — and no cookie, no identifier kept on your machine, and nothing that can find the same person tomorrow. That last part is not a detail, it is the whole reason this was acceptable: a counter that needed a consent banner would have cost every visitor a dialogue box, and knowing which pages are quiet is not worth that.
- ChangedThe privacy policy gained a section about it, a row in the lawful-basis table, and a correction to the subprocessor list, all in the same release rather than a later one. It used to say “no analytics, nothing running, nothing to opt out of”, and shipping a counter while that sentence was still on the page would have been the actual problem — larger than the counter, and harder to notice.
Somebody in charge
The site has had an admin role since the first migration and no account has ever held it, because only an admin can make one.
- FixedNobody could be an admin. Every account is created as a member, and the rule that decides who may change a role has always been “an admin, and nobody else” — so on a fresh site there was no first one, and no request from any account could produce one. The site-wide report queue has been sitting behind a check that nothing could pass, and suspending an account was reachable from no interface at all.
- NewA command that grants a site role by email, run by whoever owns the deployment. That is the honest shape of it: becoming the first admin is an act of the person holding the database password, not a request anybody can make. It writes to the same append-only log every ban does, with no name against it, because a machine did it.
- NewAn administration panel, for admins alone. Every account with its role, suspensions that can actually be imposed and lifted, every campaign on the site, and the report queue — which keeps its old address too, since a moderator needs the queue and none of the rest.
- NewCounts of what is on the deployment: accounts, campaigns, threads, characters, dice rolled, and whether the reference library was ever loaded. A health check rather than a dashboard — nothing here is a graph.
- NewA site cannot demote its way to having no admins. The last one is refused with a message rather than silently ignored, which is the same rule a campaign has had about its last GM since campaigns existed.
- NewAdmins and moderators are marked as such on their profile and in a campaign’s member list — the two places you look somebody up on purpose. Deliberately not beside every name in a scene: a tag on a moderator mid-conversation is an argument-ender.
- ChangedBeing an admin is not a way into anybody’s campaign. The panel lists every campaign by name and size and links into none of them, because the wiki, the boards, the maps, the handouts and the dice are each guarded by membership — and that does not change for whoever runs the server.
- ChangedAn email address can be searched for and is never shown. Finding the account behind a message sent to the support address is a lookup; putting three hundred addresses on a page somebody scrolls past is not the same thing, and only the first is worth doing. The query that feeds the panel has no email column in it at all, so there is nothing to render rather than something the page declines to.
- ChangedThe privacy policy says what an administrator can see, because it now says something they could not see yesterday. It also corrects a line about email addresses that was true until this release and would not have been afterwards.
A hall with a heart in it
- ChangedA real mark, in place of U+2302 — the house character — set in type. The old icon was a stroked outline because the header set that glyph and the two had to match; the constraint was right and the conclusion was backwards, since the answer to a typographic header was never to make the logo look like a font fallback. The header, the tab, the home-screen icon and the 404 page now draw one mark from one set of eleven coordinates.
- ChangedFilled rather than stroked, which is what makes it survive being sixteen pixels wide: a solid silhouette loses detail as it shrinks, and a pixel-and-a-half outline loses the shape.
Six things that were already here
Almost none of this is new information. It is dice already rolled, content already licensed, a flag already ticked and an evening already played — none of which anybody could look at.
- NewA dice log for each campaign, and the statistics that fall out of it. Every roll has been made by the server and written down face by face since the first week, including the dice a keep-highest threw away; there was simply nowhere to look at them. Now there is a histogram of every d20 the table has ever thrown, an average against the fair 10.5, and a count of natural 20s and natural 1s per person.
- NewThe per-person table is sorted by how much each person has rolled rather than by their average, because somebody who rolled three times and got two twenties is not lucky, they are barely measured. A GM and a player at one table can honestly see different numbers: secret rolls count for the people allowed to see them, which is the secret roll working rather than an error.
- NewHandouts: a letter, a torn map, a portrait, prepared whenever you like and given to the party at the moment you choose. An unrevealed handout is invisible rather than locked — a player cannot see that six things are being kept from them, which is its own kind of spoiler.
- NewA handout’s picture is refused to players rather than merely unlinked. The storage rule looks up the handout the file belongs to and asks whether it has been revealed, so an unguessable path is the lock and not the whole answer.
- ChangedThe spell and monster reference is readable without an account. Three hundred spells and a few hundred monsters sat behind a sign-in for no better reason than that everything else here does — they are world-identical, openly licensed under Creative Commons Attribution, and belong to nobody. Every spell and every monster now has its own address, and the attribution goes with them because that is the licence’s one condition.
- NewA player board, which is the campaign directory pointing the other way. Say what you are looking for, what you like playing and when you are free, and a GM with a free seat can come to you. Visible to people with an account and to nobody else: a listed campaign is a thing somebody made, and a notice is a person saying which evenings they are free.
- NewA GM answering a notice sends a single-use invite that expires in a fortnight. Nobody is added to a campaign by being invited — they follow the link, or they do not.
- NewCharacters can be published: a read-only page that works without an account and can be found by a search engine. The old “public” box has meant “the people at my table” since campaigns arrived, and it still does; this is a second, narrower question, off by default for every character that already exists.
- NewA published page shows the sheet and the biography and nothing else. Play state, the campaigns the character appears in, and the owner’s account id never leave the database — not because the page does not render them, but because the query that fetches a published character does not have those columns in it.
- NewSession recaps. A session was proposed, voted on, confirmed, and then nothing recorded what took place in it. Write it up afterwards and [[wiki links]] in the recap put that evening in the backlinks of every page it names, so an article about a tavern lists the four sessions it came up in.
- NewGive a recap an in-world year and the session becomes an event on the campaign timeline, edited rather than duplicated the next time you save. A campaign’s history accumulates as a side effect of playing rather than as homework nobody does.
- FixedCounting a person’s rolls in the last minute — which happens on every single roll, to enforce the rate limit — had no index behind it and never has. It does now.
Levelling up
The sheet knew the rules for making a character and nothing at all about advancing one.
- NewLevelling up, from the same tables that filled the sheet in when the character was made. One level at a time, because two of the things a level hands you — a subclass and an ability score increase — are choices, and a jump from 3 to 7 would either skip them or guess.
- NewHit points are added rather than recalculated, so a total that was rolled at the table, or raised by something this app has never heard of, survives getting stronger. The box is filled in with the average for your hit die plus Constitution, and anyone who rolled types theirs in over it.
- NewThe subclass is asked for at the level your class actually chooses one — first level for a cleric, third for a fighter — and keeps asking if you reached it without picking. The SRD publishes a single option per class, so there is a box beside the list for the one you are actually playing.
- NewAn ability score increase at 4, 8, 12, 16 and 19, and at the extra levels a fighter and a rogue get theirs. Two picks rather than a switch, because naming the same ability twice is how the rules put +2 into one score. Nothing goes above 20 that way, and a score already above it is left where it is.
- NewSpell slots follow the new level, ticked by default and easy to leave off for anyone whose slots came from somewhere other than the class table. Slots already spent stay spent: levelling up is not a rest.
- ChangedThe experience panel showed the level your experience came to, the sheet showed the level you were, and neither had ever mentioned the other. It now shows the level the rest of the sheet is actually using, says when there is enough experience for a higher one, and the top of the page says so too.
Flatter
- ChangedNothing on the page floats any more. Cards carried a soft two-layer shadow, which was the only soft effect in the whole design; a panel is now a fill and a hairline, and a panel sitting inside another steps up a shade rather than casting a shadow over it. Corners are tighter to match.
Findable from outside
The handful of pages a stranger is allowed to see, made legible to a search engine.
- FixedNo page on this site carried a canonical link, which leaves a search engine guessing which address a page really lives at and free to treat /groups and /groups?q=anything as two of them. Every page now names itself, and a deployment that has not been told its own domain works it out rather than pointing at localhost.
- ChangedThe front page was titled “Hearthhall” and nothing else, ten characters of brand to somebody who has never heard of it. It now says what the site is, and its description is shorter than the point where a search result would have cut it off.
- NewThe front page says considerably more about what is here: what a wiki that keeps every edit is for, what dice rolled on a server actually buy you, and six questions a stranger arrives with: who can see a campaign, what happens to a character you already have, and how to get everything back out again.
- NewSchema.org markup describing the site, the application and those questions, so a search engine can show them rather than infer them. It is generated from the same text the page renders, because structured data that describes something a visitor cannot see is a penalty rather than a shortcut.
- NewLanguage tags saying this site is in English and that English is the fallback for everyone. There are no translations, and it does not claim any.
Casters
The half of the sheet that still wanted a book open beside it.
- NewSpell slots fill themselves in from your class and level. One button for the whole table, at every level from 1 to 20. Slots you have already spent stay spent, because levelling up in the middle of a fight should not quietly refill you.
- NewYour spell save DC and your spell attack bonus, worked out and shown beside your spells. Both are the same short sum of a proficiency bonus and one ability modifier, both are wanted every single time you cast anything, and neither was anywhere on the sheet.
- NewSearching for a spell searches your own class list by default, and only the levels you have slots for. A third-level wizard looking for “fire” was being shown every fire spell in the game, most of them on a list they will never have.
- NewHow many cantrips you know, and, for the classes that prepare rather than know, how many spells you prepare each day.
- FixedA warlock’s spell slots came back on a long rest like everybody else’s. Pact magic returns on a short rest, which for the class with two slots is most of what makes it playable. Slots taken from a warlock are now marked as pact magic, and a short rest gives them back.
- FixedThe reference library has no paladin spells in it, which is how the SRD is published rather than an oversight here, so a paladin narrowing a search to their own list would have found nothing, every time. The search now widens itself and says that it did.
Making a character
The sheet knows the rules now, so you do not have to.
- NewClass, subclass, ancestry, subrace, background and alignment are chosen from the official lists rather than typed. Every one of them keeps a “Custom…” box, so homebrew is a first-class answer and not a workaround, and every character already written stays exactly as it was written.
- NewChoosing fills the sheet in. Your class ticks the two saving throws it grants and marks the skills it lets you choose from, counting them as you go. Your background and ancestry tick the skills they hand you outright. Your ancestry adds its ability score bonuses and sets your speed. Hit points come from your hit die, level and Constitution; the proficiency bonus comes from your level; initiative comes from Dexterity.
- NewNone of it is enforced. Everything worked out for you lands in an ordinary box you can type over, and when what you typed disagrees with what the rules give, the sheet says what it makes it and leaves the decision to you.
- NewArmour is chosen from the equipment table and your armour class follows from it: heavy armour ignoring Dexterity, medium capping it at +2, a shield adding two. It is the number most often wrong on a sheet filled in by hand, because it is the one that needs a lookup.
- NewWeapons. Adding an attack starts from the weapon list: damage dice, damage type and to-hit are filled in, finesse and ranged weapons use Dexterity when it is the better of the two, and a versatile weapon offers its two-handed die as a second button.
- NewWhat each choice actually gives you is written beside it: hit die, saving throws, proficiencies, ancestry traits and starting equipment. One button writes the lot into your features and equipment, where you can cut what you do not want.
- FixedAn empty ability score box showed a confident −5 beneath it, which is what a score of zero would be worth. An unanswered question now looks like one.
Menus that close
- FixedThe menus in the header stayed open once you opened one, hanging over the page until you found your way back to the button and pressed it a second time. They now close when you choose something, when you press Escape, and when you go anywhere else on the page.
- ChangedThe icon in the browser tab is now the same ⌂ the header uses, rather than a second drawing of the same idea.
Spells, monsters and a working inbox
A reference library the sheet can actually use, and the site finally telling you when something happens.
- NewYour inbox now tells you when someone asks to join a campaign you run, and tells them what you decided. Applying and then refreshing the page was the whole of it before.
- NewA notification when a session is proposed, and again when a time is confirmed.
- NewA notification when a character joins the party.
- NewDownload everything you have written, as one file from account settings: characters, posts, wiki edits, rolls, applications, your inbox. Deleting your account already worked; this is the other half of it.
- NewImport a character from a JSON export as well as from a PDF. D&D Beyond, Foundry and Roll20 all work, and a JSON export is read far more reliably than a printed sheet.
- NewSpells. Search the reference library from your sheet and keep a spellbook, so the spell slots you were already tracking have something in them.
- NewA bestiary in every campaign, with full stat blocks, searchable by name and by challenge rating.
- NewAdd a monster to a fight straight from the bestiary. It rolls its own initiative, arrives with its armour class and hit points, and several at once get numbered.
- FixedAnyone with an account could add a combatant to any scene’s turn order, including in a campaign they were not a member of and could not read. Writing to a campaign now requires being able to post in it.
Sheets in and out
Get a character in from a PDF, and get one back out again.
- NewImport a character from a filled-in PDF character sheet. The file is read in your browser and never uploaded.
- NewExport a character: print the sheet as a PDF from any browser, or fill a blank fillable sheet PDF.
- NewAttacks on a D&D sheet, each with a to-hit, damage and critical button that roll through the usual verifiable dice.
- FixedSaving throws were rolled without the proficiency bonus, so the two saves your class is best at were understated. Sheets now record which saves are proficient.
- ChangedCharacter pages print properly: one column, no buttons, and readable whichever theme you use.
Campaign directory and applications
The first thing on this site a stranger can see, and only when a GM says so.
- NewA public campaign directory. A GM can list a campaign so people can find it; the wiki, scenes, maps, sessions and member list all stay private.
- NewApplications: ask to join a listed campaign with a short pitch, and optionally attach a character for the GM to read.
- NewAn applications queue for GMs, with a count in the campaign nav. Admitting someone also puts their character on the party roster.
- ChangedOnly a campaign’s owner can list it publicly. A co-GM can run everything else and cannot advertise the game.
Party, sessions and world maps
- NewA party roster per campaign: everyone’s hit points, armour class, passive perception, spell slots and conditions on one page.
- NewSession planning. Propose several times, everyone marks each yes, maybe or no, and one gets confirmed. Times show in your own zone.
- NewMinecraft bases place themselves on a campaign map from the coordinates on the character sheet.
- NewMaps, with pins that open a wiki page or descend into another map.
- NewAn in-world timeline of events, and a lore graph of how wiki pages relate.
- NewSearch across everything you are allowed to read.
- NewSign in with Discord or Google.
- NewRoll ability scores on the server, and tick skills rather than typing them.
- NewSecurity headers with a nonce-based content security policy.
- NewModeration: reports, a per-campaign queue, an observer role that can read but not post.
- Fixed“Staff” on a report meant the site operator rather than the campaign’s own moderators.
First playable
- NewAccounts, private campaigns and invite codes.
- NewA wiki per campaign with [[wiki links]], templates, revisions and backlinks.
- NewPlay-by-post boards and threads.
- NewDice rolled on the server, with every die recorded so any result can be checked afterwards. Secret rolls for GMs.
- NewCharacter sheets for D&D, Minecraft and freeform play.
- NewAn initiative tracker for combat played out over days.
Something here not working the way it reads? Tell us.