-
v4.3.0
StableAll checks were successfulCI / Bot/backend version sync (push) Successful in 42sRelease / Create Forgejo release (push) Successful in 12sCI / Backend lint (ruff) (push) Successful in 55sCI / Summarisation accuracy eval harness (stub provider) (push) Successful in 1m29sCI / Frontend tests, audit, and build (push) Successful in 2m16sCI / Bot tests and audit (push) Successful in 2m36sCI / Docker image build (push) Successful in 4m13sRelease / Build and push versioned images (push) Successful in 3m53sCI / Backend migration, tests, and audit (push) Successful in 10m13sCI / Synthetic session harness (no GPU, no LLM) (push) Successful in 14m47sreleased this
2026-09-06 09:51:10 +00:00 | 113 commits to main since this releaseProduct Surface: Navigation, Attention & Feedback. The features Quest Board already had are now findable, acknowledged and self-diagnosing: a navigation bar on every page, one name for each thing, a "Needs you" list on the dashboard, RSVP on the web, a session page that shows every post-session task, a Prep workspace with a front door and a sheet that looks forward, a wiki you can search and review from one place, a Discord bot that answers back and explains itself, and an invite link you can paste. Structural fixes, not a redesign; that is v4.4.0.
Three migrations, applied in this order by the migrate container:
f0ab1c2d3e4f(a delivery-status column on campaigns, #369),fa0b1c2d3e4f(an RSVP status on session attendance, #370),0b1c2d3e4f5a(post-session task status on sessions, #380). All are additive; nothing is backfilled. Head after upgrade:0b1c2d3e4f5a.Bot API contract v1, unchanged. Everything new on
/api/bot/*is additive:POST /bot/campaigns/{id}/delivery-status,GET /bot/guilds/{id}/campaigns,GET /bot/guilds/{id}/sessions/recordable, astatefield onlink-status, areasonfield on/ask, and a link field in every notification payload. An older bot works against this backend; an older backend leaves a newer bot's new features quietly off. Deploy both images together as usual.BOT_EXPECTED_APP_VERSIONis bumped so the bot's startup log matches.One new public route on the backend:
GET /api/invites/{code}resolves an invite code to a campaign preview so/join/<code>links work before sign-in. The code is the secret; the route is rate-limited and a wrong code is an ordinary 404. Nothing else on/apiis unauthenticated.Two HTML pages served by the backend (the account-linking outcomes) carry a slightly relaxed Content-Security-Policy that allows inline styles for
text/htmlresponses only; JSON responses keep the strict policy.No new settings. Nothing to add to
.env. Operator notes carried from the patch releases: the Message Content toggle in the Discord Developer Portal can be turned off; if a campaign's notification channel is misconfigured the campaign page now says so, and the per-field "Test" buttons on the Edit form prove a fix. The old/sessions/<id>/recordingaddress redirects to the session page, which is now the one live-session screen.Added
-
[webapp] You can now RSVP to a session in Quest Board (#370). Saying whether
you were coming used to mean reacting ✅ or ❌ to a message in Discord — so if
your group does not live in Discord, or you never linked your account, you
could not answer at all, and nobody could see who had. A confirmed or
tentative session now has an "Are you in?" control at the top of its page with
Yes, Maybe and No, and the whole party can see the roster of who has answered
and who is still to. It is the same answer either way: a reaction in Discord
shows up in the roster, and an answer given here shows up for everyone. Your
GM's after-the-fact attendance list is untouched — saying you are coming is not
the same as having been there. -
[webapp] A "Needs you" list on the dashboard (#368). The dashboard showed
your campaigns and nothing else, so the only way to find out that a vote was
waiting on you, or that a session next week still needed your RSVP, or that a
transcript had been sitting ready for you to approve, was to open each
campaign and look. Anything actually waiting on you now appears at the top of
the dashboard — open votes, missing RSVPs, sessions in progress, and for GMs
transcripts to review and suggested wiki updates — and every line takes you
straight there. When nothing is pending the section is simply not there. The
"Next session in 3d 4h" line on each campaign is now a link to that session. -
[webapp] A "Post-session processing" checklist on every session (#380).
Finishing a recording sets six things going: the transcript and summary, the
suggested wiki updates, the campaign storyline, the session's journal entry,
the next session's title ideas, and the recap email to the party. Only the
first two ever said anything, so if the storyline never rebuilt or the recap
email was refused by the mail server, nothing anywhere told you — it looked
exactly like a job that had not got round to it yet. All six now appear as a
checklist on the session page, and "failed" reads differently from "hasn't
run" and from "deliberately skipped" (journal entries turned off, campaign
archived, storyline written by hand). The recap email says whether it is
queued, sent, or failed. Includes a migration (0b1c2d3e4f5a), which
adds one column and backfills nothing — sessions processed before this
release read as "no record", because that is the truth about them. -
[webapp] A navigation bar that is the same on every page (#378). Until now
the only thing every screen shared was a corner strip with your name, Profile
and Sign out; getting from a session to the wiki meant walking back up the
breadcrumbs one page at a time. There is now a single bar across the top of
the whole app: the Quest Board wordmark always goes home, a switcher jumps
straight to any of your other campaigns, and while you are inside a campaign —
including on a session, its recording page or its shelf — the bar carries that
campaign's Sessions, Prep, Wiki and Highlights. The two wiki links on the
campaign page also stop opening a second browser tab, so the back button
works through the wiki again. -
[bot]
/help, a welcome when the bot joins a server, and a presence that
points at both (#373). The bot arrived in a server and said nothing, ever:
there was no command list, no message on join, and nothing under its name in
the member list, so the only way to find out that/nextexisted was to be
told by somebody who already knew./helpnow lists every command with one
line each; joining a server posts the three setup steps — link a campaign to
this server (quoting the server's own ID, ready to paste), everyone runs
/link, then try/help— and the member list reads "Watching Quest Board ·
/help". The welcome also warns that Discord takes up to an hour to roll
out a new bot's slash commands, because the first impression of a working
install was otherwise a server where/helpdid not exist. -
[webapp] The wiki has a search box (#396). Until now the only way to
reach an article was to know which of thirteen categories it had been filed
under and scroll the list — fine for a campaign with twenty articles, useless
for one that has been recorded for a year. There is now a search box on the
wiki's front page and in the article page's category rail. It searches every
article in the campaign rather than just the ones already on screen, and it
looks at each article's text and its alternative names as well as its title,
so "the innkeeper with the limp" finds the innkeeper even when nobody at the
table remembers his name. -
[webapp] An invite link you can actually send someone (#387). Inviting a
player used to mean finding a 12-pixel "▼ Show invite code" disclosure under
the Archive and Delete buttons, copying eleven characters out of it, and
hoping the recipient worked out that they had to create an account, find the
Join button on their own dashboard, and paste it in. There is now an Invite
players control in the member list, which gives you a link — paste it into
your group chat and whoever opens it sees which campaign they have been
invited to and who invited them, signs in if they need to, comes straight back
to the invite, and joins. It works for somebody who has never heard of Quest
Board. The code is still there underneath for when a link will not survive the
trip, and the "+ Add" member search now says so too, instead of ending at "No
users found." — which it always did for the one person you were most likely to
be looking for. -
[webapp] A first-run checklist on a new campaign (#387). A campaign you
had just created looked exactly like one you had finished setting up: an Edit
form, a member list of one, and an empty session list. Four things actually
need doing — set the timezone, invite the players, connect Discord, schedule
the first session — and each was discoverable on its own but not as a set.
They now appear as a short card at the top of the campaign page, each with a
button that takes you to the control that does it rather than near it. Items
tick themselves off from the campaign's own state, so a GM who did all four
last year never sees it, and Dismiss makes it go away for good on that
campaign. -
[webapp] Guides for GMs and players, one click from where you are (#390).
Everything written down about Quest Board was for whoever installs it. A GM
running their first campaign, or a player handed an invite link, had the
interface and nothing else. There are now two guides — "Running your first
campaign" and "Joining a campaign" — that live in the app, linked from the
bottom of your dashboard, from the invite page and from the sign-in page. They
are readable without an account, on purpose: the reader who needs "Joining a
campaign" most has not signed up yet. The sign-in page also stops describing
the product as scheduling, which it has not only been for a long time, and its
button says "Sign in" rather than "Sign in with SSO". -
[webapp] Players get the "Previously on" recap too (#388). A short recap of
last session, and the quests still open, has been waiting at the top of the
GM's shelf since v4.1 — where nobody but the GM could ever see it. The same
strip now sits at the top of a session's page and of "At the table", for
everyone in the campaign, while the session is upcoming or in progress. It is
the same recap from the same place, narrowed rather than rewritten: players
see the open quests your GM has marked visible to the party, and not the ones
they haven't. You can fold it away, and it stays folded for that session on
that device, but it comes back with one click — it is not a dismissal you can
make by accident and never undo. -
[webapp] Three things you could do, but had no way to undo or reach
(#389). Showing a card to the table was one-way: once revealed it stayed on
the players' table view for the rest of the session, however plainly you had
meant to reveal a different card. The shelf now lists what is currently up,
with an "Un-reveal" on each — and the players' view drops it on its next
refresh, exactly as it picks up a reveal. XP was the same shape of problem
from the other side: the ledger showed totals only, so a mistyped award could
be made and never unmade. Every award is now listed, party and per-member,
each with a delete that names the award it is about to remove. And "Add to
Calendar" offered Google and nothing else, which is a dead end if you keep
your calendar in Apple Calendar, Outlook or Thunderbird; there is now a
"Download .ics" beside it, offered wherever the Google link is.
Changed
-
[webapp] One screen for a live session (#386). Running a session meant
keeping two pages open that described the same recording and disagreed about
it. The session page had a "Recording & Transcript" section; a separate
Recording page had the live picture — the clock, who the bot could hear, who
was in the voice channel and silent, and Start and Stop — plus a second copy
of the summary you could not edit and a second attendance list whose toggle
said "✓ Here" where the session page said "Present". Worse, the link to that
page only appeared once a session had a confirmed time, so the one moment you
most want to check the bot can hear the table — before committing to a date —
was the one moment the controls were out of reach. All of it is now on the
session page: a Recording panel with the live clock, per-speaker capture,
who is present but not captured yet, Start and Stop, and the "connection
lost, showing the last reading from … ago" honesty added in #377. It is there
from the moment a session is proposed, and the shelf — the screen a GM
actually has open during play — now has a Recording link straight to it. The
summary is editable in one place and read-only in none, attendance says
"Present" or "Absent" wherever you meet it, and the roster is available from
the moment a session is under way rather than only after it is over. The old
/sessions/…/recordingaddress still works: it takes you to the panel, so
bookmarks and older Discord links are unaffected. -
[webapp] One name per thing, across the whole app (#379). The same concept
answered to a different name on almost every screen, which made two screens
about the same thing look like two different features. The GM prep workspace
was "GM Workbench" in its own heading, "Session Prep" in the palette and
"Session Prep Sheet" in the panel; it is Prep everywhere now, and its
output is "prep notes". The wiki landing page said "Wiki" in the breadcrumb
and "Campaign Story" in its heading; it says Wiki. Plot threads were
"Thread Tracker", "loose ends" and "open loops"; they are Quests, and the
shelf's cold open lists "Open quests". The Quote Board is Highlights. A
suggested wiki entry was "AI Proposals", "Entry Proposals", "Bot Proposals" or
"lore proposals" depending where you stood — and "Bot" was wrong besides,
since the backend worker writes them, not the Discord bot; they are
suggested wiki updates. The generation history rail and its filter now
name each tool ("Session Prep", "NPC Voice Cues") instead of printing the
backend'ssession_prepandnpc_voiceat you. The link from a session to
its recording page says "Recording", not "Dashboard". Nothing moved: every URL
is unchanged, so bookmarks and Discord links still work. A character's
timeline also stops rendering twice on a wiki article — the full section
stays, the cramped duplicate in the infobox is gone. -
[webapp] "Approve" on a suggested wiki update stops meaning two different
things (#385). One button either wrote the article straight into the wiki
or carried you off to a merge-review page you had not asked for, depending on
whether the suggestion changed an article you already had — a difference
signalled only by a small "Update" chip. A suggestion that creates a new
article now says Approve; one that changes an existing article says
Review merge…, so the destination is on the button. The words either side
of that click have been made true as well: the queue promised the suggestion
would be "appended" and the review page then offered to "replace the
article"; every draft that was not a merge or a stat conversion called itself
an "LLM rephrase", generated backstories included; and the approve button
read "Approve and replace article" even for the two kinds of draft that
replace nothing at all. Each kind is now named for what it is and its button
for what it does — "Generated backstory for…" approves as Add to article,
a stat block approves as Approve stat block and says the article's text is
left alone. Alongside that: all four actions in the queue now show they are
working, so a second click cannot approve or discard the same thing twice;
when one fails it says so on the suggestion that failed, instead of in a
browser alert box — the last one in the product; and approving an article
confirms it and offers a link to the article you just made, rather than
making the row vanish and leaving you to guess.
Fixed
-
[webapp] Pages that are not for you now say so, instead of vanishing or
bouncing you (#382). A player who followed a Prep link a GM had shared was
redirected to the campaign page with no message, which reads as a broken link
rather than as "Prep is the GM's workspace" — it now says which it is, and
offers the way back. Four wiki pages ended a player's navigation with the
words "GM access only." on an otherwise empty screen, with nowhere to go but
the back button; each now explains the restriction and links back to the
article, the wiki, the campaign and the dashboard. Opening an article's
/editURL without permission silently showed the ordinary read view, as
though the link were broken; it says you can read but not edit this one. The
"Add to shelf" control disappeared entirely when a campaign had no upcoming
session, so the answer to "why can't I put this on a shelf?" was a blank
space; it now says there is no upcoming session and points at where to
schedule one. A highlight's "Draft" badge said only that it was not visible
to players, never what would make it visible; it now names the thing that
publishes it — approving the session summary, which is on the same page. And
the archived-campaign banner named no way back: archiving is something a GM
can do, un-archiving is not, so the banner now says an instance administrator
restores it, and that scheduled sessions stay on the calendar but stop
sending reminders. -
[webapp] Prep's session pickers open on your next session, not the one
furthest away (#302). Every session dropdown in Prep — Session Prep, Beat
Planner, the Name Generator's session context, Series Titles, "Add to shelf"
— was seeded from whichever session the API happened to list first, which is
the most recently created one. For a weekly game that is the last occurrence
on the calendar, so a GM who opened Prep to plan Tuesday was silently pointed
at a session three months out, and notes saved there landed on the wrong
night. Those lists are now ordered by when the session actually is, soonest
first (undated ones last), and default to the session in progress if there is
one, otherwise the next one up. -
[webapp] Prep notes can no longer be wiped by a button you did not mean to
press (#303). "Save Notes" in the Beat Planner is now inert until you have
actually changed something, so an editor you opened and did not type in
cannot write an empty note over what was stored — and if the notes fail to
load at all, the box and the Save button are both disabled and say why,
rather than presenting a blank page you could save. "Append to prep notes" on
a generated prep sheet re-reads the stored notes at the moment you click it,
so notes you edited in another tab since the sheet appeared are kept, and the
button is not offered at all when those notes cannot be read. Notes written
by the prep sheet also show up in the Beat Planner without a reload, and if
you had unsaved typing when that happened, your typing wins and you are told. -
[webapp] Prep no longer throws away what it just generated (#304). Switching
tools in Prep wiped the sheet you were reading, and "Re-open" in Generation
History only moved you to the right tool and then showed you an empty panel —
even though every run had been saved on the server the whole time. Re-open now
brings the run back: its output, and the inputs it was made with. Opening a
tool also brings back its last run when that run is still about what you are
looking at — the same session, say — and deliberately shows nothing when it is
not, rather than handing you a prep sheet for a session that already happened. -
[webapp] The generated prep sheet stops handing you back last session
(#305). The only forward-looking thing the prep prompt had to work with was
your notes for the upcoming session — which were almost always empty, because
nothing in Prep ever loaded them (#302, #303). Left with a pile of recent
summaries and asked for a prep sheet, the model wrote a recap. Three changes:
the notes box for the selected session is now in the Session Prep panel
itself, so writing down where you want the evening to go is part of asking
for a sheet; a "What I want from this session" box steers one sheet without
being saved anywhere ("they finally meet the Duchess", "keep it in the
sewers", "no combat"); and the prompt now says what the recent summaries are
for — build on them, do not repeat them — with every scene and secret
required to move past where they left off, and only "loose ends" allowed to
look backwards. -
[webapp] Prep has a front door, opens on the right tool, and its output
goes somewhere you can find (#374). You could only reach Prep from the
campaign page or the nav bar, and it opened on the Beat Planner with a
campaign-wide picker that had already chosen a session — usually not yours.
Every upcoming session row on the campaign page, and every session page you
run, now has a Prep this session button that takes you straight to the
prep sheet for that session. Prep opens on Session Prep. Untitled sessions
read as their date in every picker instead of four identical rows saying
"Untitled session". The three unlabelled buttons under a generated sheet
("Append to prep notes", "Replace prep notes", and a second shelf picker) are
now one Save to this session and one Add to shelf, each of which names
the session it wrote to and links there. Generation History refreshes when a
run finishes, instead of insisting there were no generations while one sat on
the screen beside it. And the tool palette is six entries — Session Prep,
Story Arcs, Quests, NPCs, Names, At the Table — instead of thirteen siblings:
nothing was removed, the smaller tools now sit inside the job they serve. -
[webapp] "Processing…" now tells you how long it has been, and how long it
usually takes (#381). A spinner with no clock is indistinguishable from a
hang after about ninety seconds — which is roughly when a GM decides the thing
is broken and hits Retry, adding a second job to the queue that was the delay.
The session page, the recording page and every Prep tool now count the time
elapsed and say what normal looks like beside it ("usually 2–5 minutes for a
3-hour session, longer when other recordings are queued"). A Prep run that
overruns also points at "Generation History" by its actual name, instead of
telling you to check "the history rail", which is not a thing on the page. -
[bot/webapp] Discord account linking no longer dead-ends (#392). Two of
the ways linking can fail answered the browser with raw JSON — literally
{"detail":"Link token is invalid or expired"}on a blank page — and one of
them was a trap. If the Discord account was already connected to a different
Quest Board account, the bot's poller could not tell that from "hasn't
clicked the link yet", so ten minutes later it DMed the player that their
link had expired; they ran/linkagain, got the same silence, and went
round a loop that/linkcould never resolve, because the fix was
/unlinkon the other account and nothing had ever said so. Both failures
now render a real page that names the next step, the bot reports the actual
outcome (and reports it as soon as it happens, rather than at the end of the
window), and the conflict message names/unlink. Two smaller silences went
with it: a "you need to link" DM to somebody with DMs closed used to vanish
entirely — it now falls back to a short self-deleting note in the channel —
and the vote reminder that lists players who are not linked now tells them
to run/link. The profile page names the command too, instead of alluding
to "the bot's account-linking flow". -
[bot/webapp]
/record startknows which session you mean, and a restart no
longer swallows a recording in silence (#393). The command asked for a
session ID that nothing in Discord could give you —/nextshows one session
and omits its id,/historylists only finished ones — so the answer was to
go and copy a UUID out of a browser. It now offers this server's upcoming and
in-progress sessions as you type, and a session that does not exist is
refused when you start rather than discovered at the end of the evening, which
is when the mistake used to surface. Every recording started from Discord also
announced itself as "Recording started — Unknown Session", and said it again
at upload, because the slash command fetched the session's details and then
dropped the title; it now uses the real one./record stopno longer leaves
"Quest Board is thinking…" on screen for ever — it answers the person who ran
it, as well as posting to the channel. And a bot restart mid-session used to
leave the channel showing "🔴 Recording started" with no ending,/record stopinsisting no recording was active, and a GM with no way to know the
audio had in fact been kept: the active recording is now remembered outside
the process, so when the bot comes back it says what happened to the audio —
recovered and being transcribed, kept and awaiting a retry, or never captured
— and/record stopanswers honestly instead of denying the session
happened. Failure messages have been rewritten for the people reading them:
no raw exception text in a public channel, and "a GM can retry from the
session page" with a link, rather than advice to use a console that a hosted
customer does not have. -
[bot/webapp] Discord now tells you what actually went wrong (#373). Every
Quest Board API call the bot made ended the same way when it failed — "Could
not reach Quest Board right now. Please try again shortly." — including when
the backend had answered with something you could act on. "LLM endpoint not
configured. Set it in Admin → Bot Settings." was being thrown away and
replaced with a message that said the service was down, which it was not.
The bot now shows the backend's own sentence when the backend is answering
rather than failing (a 4xx, or a 503 naming a dependency that is not set up),
and keeps the generic line for a genuine outage or an unhandled error, where
it is the only true thing to say. Related:/next,/questsand/history
used to answer "nothing scheduled" for a server nobody had finished setting
up — they now say when no campaign is linked to this Discord server, name
the field to fill in, and quote the server's ID;/record start's "you are
not the GM" refusal now mentions that Quest Board only recognises a GM whose
account is linked, and points at/link; and/askon a campaign with
nothing recorded finally gives the "record a session first" advice it always
had written down, which a placeholder answer from the backend had made
unreachable. -
[bot/webapp] A wrong Discord channel ID no longer swallows every
notification in silence (#369). The bot notification channel is a snowflake
a GM types into a plain text box. Get it wrong — a typo, a channel that was
later deleted, one the bot cannot see or cannot post in — and every
notification that campaign would ever send vanished, permanently, with no
error anywhere: the bot logged a warning nobody reads, and the durable event
queue acked the event exactly as if it had been delivered. The campaign simply
went quiet, and the only visible clue was the absence of messages nobody was
looking for. The bot now records why it could not deliver, against the
campaign, and the campaign page carries a warning at the top of the page —
outside the collapsed Edit form, where the broken field lives — naming the
actual problem ("Discord has no channel with that ID", "the bot isn't allowed
to see that channel", "give it Send Messages permission") and offering a
button that opens the field. The warning clears itself the moment a
notification lands. The event is still acked, because a message the bot cannot
post must not wedge the queue for every other campaign — but if the failure
cannot even be recorded, that now goes to the log as an error rather than
disappearing too. The "Send test message" button is fixed in the same breath:
it was admin-only on a page any GM can open (so most GMs got a permission
error), it reported success on having queued the attempt rather than on
anything arriving, and it tested the bot channel and the webhook as one thing.
There are now two buttons, one per field, each waiting for the real answer,
and the channel ID field itself rejects anything that is not 17–20 digits
before you can save it. Adds a migration (f0ab1c2d3e4f). -
[bot/webapp] Voting in Discord now answers back, and a GM can change one
time without cancelling the vote (#371). Reacting to a poll or an RSVP
message did nothing visible: no confirmation, no error, and a vote that failed
to reach Quest Board looked exactly like one that landed. Every reaction now
gets a short reply in the channel that mentions you and deletes itself — "your
yes for Option A is recorded", or the reason it was not — including,
at last, the rule nobody could have guessed: removing a reaction records a
no for that time, not a blank. The poll message says so itself now, and
says to use Quest Board for "maybe", which reactions cannot express. Four
further asymmetries go with it. A vote cast in Discord now fires the same
"🗳️ Vote Update" post that a vote cast in the web app always did, so the
channel's own tally stops going stale. A reaction on a poll for an
already-confirmed session is refused instead of quietly recorded, the reaction
is taken back off, and the player is told when the session was confirmed for —
and the poll message is relabelled "Voting closed" the moment a time is
confirmed, so it stops inviting reactions in the first place. A GM can add or
remove a single time option on an open vote from the session page, keeping
every vote already cast; the only previous route was "Reopen for voting",
which replaced the slate and discarded them. And when the bot has to fall back
to keeping its poll bookkeeping in memory — no Redis, or Redis unreachable —
it now says so loudly at the moment it starts, and logs every reaction it
drops, because the symptom otherwise is a channel full of polls that look
perfectly alive and record nothing. -
[webapp] The wiki updates the app suggests are findable again (#375). On
the wiki's own front page the only way into the suggestions queue was a link
in the left-hand rail, and that rail is hidden on anything narrower than a
tablet — so from a phone there was no route to it at all. It now sits beside
New article in the main column, with the number of pending suggestions on
it, at every screen size. The campaign page carried a second, cut-down copy
of the queue: it left out suggested relationships entirely, truncated every
suggested article to three lines, and disappeared when the queue was empty —
which is exactly the moment a GM hunting for it needed to be told there was
nothing waiting. That copy is gone, replaced by one row that is always there
and always says which of "3 suggested wiki updates", "no pending suggestions"
or "couldn't load them" is true, with Review going to the one page that
shows the whole queue. Both pages now tell a failed read apart from an empty
one, instead of showing you an empty queue when the request simply failed. -
[webapp] A wiki draft can no longer claim to be generating for ever, and a
failure in one panel stops taking the whole page with it (#395). While the
LLM writes a draft, the review page asks the server for it every couple of
seconds — and that check only understood one kind of failure. A server error,
a dropped connection or a worker that died mid-run left "Generating draft…"
on screen indefinitely, with nothing to suggest anything had gone wrong. The
page now says when a check fails, stops pretending it is still watching after
three minutes, and offers Check again beside the existing reset. Three
other failures used to replace an entire page with a single red line: a wiki
article's edit history failing to load, a Restore of an old version
failing, and the wiki's Load more failing each wiped out the article — or
the whole campaign story — you were reading. Each now reports itself beside
the control that failed and leaves the page alone. And Full regenerate,
which throws the campaign story away and rewrites it from every session, now
asks first, like every other destructive action in the wiki. -
[webapp] The wiki's category list stops running out after 200 articles
(#396). The article page's category rail asked for the entire wiki in one
request, and the server sends at most 200 entries — so on a campaign with
more than that the rail simply ended, with nothing to say anything was
missing, and every article past the cut-off was unreachable by browsing. It
now pages the way the wiki's front page already did, with the same Load
more (200 of 250) button, so both lists reach the end of the wiki. -
[webapp] Things that failed now say they failed (#377). A dozen places in
the web app treated a failed request as if nothing had happened, so there was
no way to tell a working screen from a broken one. The worst of them was the
recording page: if the connection dropped mid-session, the page redrew itself
as "No active recording", idle, with a Start Recording button — while the
bot was still recording in Discord — because "the server says nothing is
recording" and "we could not reach the server" were the same value in the
code. It now keeps the last thing the server actually said, says "Connection
lost, retrying…" over it with how long ago that was true, and clears the
warning the moment it hears back; where it has never heard anything, it says
Unknown rather than guessing at the answer that invites a second
recording of the same evening. The players' table view says the same thing
when its own polling stops working, instead of quietly showing a frozen list.
Elsewhere: a vote the server refused, and a session-shelf card whose new
position never saved, both now say so and offer to try again — the shelf was
the sneakiest, because the board looked right until the next reload put every
card back. A session's attendance and its loot & XP stop reporting a failed
read as an evening where nobody came and nothing was won. The last session's
recap, the title suggestions on a new session, and Prep's name pre-generation
each say when they could not load rather than simply not appearing. And in the
wiki, "Check for link suggestions" answers "No link suggestions found"
instead of doing nothing visible, and a stat block whose game-system schema
could not be read says why its labels have turned into raw field names.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-