Releases
Changelog
Every release, newest first. Upgrading is always the
same: upload the new files over the old ones. The zip carries no data/ folder, so
your board cannot be overwritten, and any database migration runs on the next page load.
Skipped versions are fine: the migration is a ladder, and a board arriving from any older
release climbs every rung in one go.
Get these in your inbox
Every entry on this page went out as an email first. Leave your address and the next one comes to you.
Release news only. Never sold, never shared. One click to leave.
Past issues and
RSS if you would
rather not hand over an address at all.
1.7.4 · September 2, 2026 · current
MySQL boards get their doors back
A board running on MySQL or MariaDB crashed every door game on its
second visit: Isle of Morrow died coming back through the gate, HILO lasted about three rounds,
and the log filled with "Duplicate entry ... for key door_kv.PRIMARY". The report that cracked
it came from the field with the diagnosis attached, and the diagnosis was right.
MySQL reports how many rows an UPDATE changed; SQLite reports how many
it matched. When a door wrote a value the row already held, MySQL answered zero, ATDT read zero
as "no such row", and the repair INSERT collided with the row that was there all along. SQLite
boards never saw it, because SQLite never says zero for a row it found.
- One statement now, on both engines. Every key-value write is a native upsert:
INSERT ... ON DUPLICATE KEY UPDATE on MySQL and MariaDB,
INSERT ... ON CONFLICT DO UPDATE on SQLite. There is no second guess to get
wrong, and no race between two statements.
- Five writers converted. The door key-value store (the crash itself), door score
awards (the same crash when an award added zero), board settings (which had been quietly
throwing and catching a key violation on every same-value write on MySQL), menu-scope memory,
and push subscriptions, which now provably keep their first-subscribed date through a
refresh.
- No data was harmed. The crash always fired before a wrong write could land. Upload
the release and the same board, on the same database, simply works; nothing needs to be
cleaned up or re-entered.
- Proven on a live server. The MySQL test suite now replays the reported failure
verbatim against a real server, alongside the same test on SQLite, so the two engines cannot
drift apart on this again.
The door engine
- A delete-line no longer silences a door. The ANSI code a door sends to delete a
screen line is byte-identical to the start of "ANSI music", and the door stream treated it as
music: it swallowed everything after the first delete-line while waiting for a music
terminator that never came. A door that used delete-line went quiet mid-screen, and quitting
it could leave the seat hanging because the goodbye handshake was swallowed too. The stream
now passes the code through, and the terminal honors delete-line and insert-line properly,
scrolling the region the way a real ANSI terminal did.
- A switch for doors that stall on a fast machine. The emulator's code compiler
mis-runs one rare pair of CPU instructions, and a Turbo Pascal door built with the common
"Runtime error 200" patch can park in its own delay loop forever: the door starts, then sits
silent, worse the faster the caller's computer, and not on every boot. A new optional line in
a door's manifest,
"jit": "off", runs that door on the emulator's slower, exact
interpreter instead. No shipped door needs it yet; the switch waits for the first one that
does.
- Usurper gets its care sheet. Usurper reads its 2 MB overlay file over the board drive
constantly unless started with its
/X switch, and its daily maintenance has its
own list of traps: the wrong switch never exits, a misplaced USUTEXT.DAT stops an unattended
run at "[Press a key]", and a deleted DATE.DAT punishes the next caller with a half-hour wait.
All of it is measured and written down in USURPER.md in the doors folder, next to the engine's
README.
The smaller items
- The caret keeps its colors to itself. The blinking cursor wore a tiny blue dot on its
left and a red one on its right. The terminal canvas was inviting the browser's LCD subpixel
smoothing, which fringes every glyph edge in red and blue; the lone blinking underscore was
where the eye finally caught it. The canvas now uses neutral smoothing: the dots are gone and
the cursor is exactly as it was.
- Single-key commands echo. Press a hotkey and the character you typed now prints at the
cursor for the beat it takes the board to answer, the way a real terminal felt. The next
screen paints over it, and a guard at the last column keeps a stray echo from ever scrolling
the screen.
Upgrading
Upload the release over your install, keeping your data/
folder. No schema change: the database ladder stays on its 1.7.0 rungs, no migration runs,
and no settings change.
1.7.3 · August 28, 2026
A cursor at every prompt
A release about manners at the prompt and honesty on the wire. The tour
a caller walks after the password is now yours to arrange, or silence, from the console; every
prompt on the board finally has the blinking cursor a real terminal always kept there; and
under the DOS door machinery, a season of running a full DOS board on this engine paid off five
debts, from hangups that took twenty seconds to be noticed to a transfer flood that could crash
a game on slow hosting. Overlay the files and you are done: no database changes this time at
all.
Arrange the logon tour, or silence it
The cards between the password and the main menu, the welcome
screen, unread bulletins, auto-message, rumor and last 10
callers, have always run in one fixed order. Settings grew The logon tour: give each
stop a position or turn it off, and the board walks your arrangement. Turn everything off and a
caller lands straight at the main menu, the way a minimalist board likes its mornings.
Stops with nothing to say still skip themselves, exactly as before. Two
courtesies keep their seats whatever you arrange: the one-time email ask when an account has no
address on file, and the "you have mail" check when letters are waiting. A board that never
touches the setting runs the classic order, unchanged.
A cursor at every prompt
A caller filed it plainly: "the cursor doesn't blink at the prompt as it
does on the main menu." The truth was starker. Outside a typed-input field the prompts had
no cursor at all, and a main menu only showed one where the board's own art happened to
paint a blinking cell. The terminal now keeps a classic blinking underscore at the resting
position of every hotkey prompt: menus, pause lines, pagers, the whole logon tour.
It is drawn over the screen, never written into it, so art under the
cursor survives untouched; typed fields keep the caret they already had, and a dead line shows
nothing, as it should. Same behavior in every browser, Edge included.
The user list breathes
On a full page of the user list, the next-page prompt sat flush against
the last caller listed. It now sits a blank line below, like the board's other pagers.
For the DOS doors: a hangup is heard the moment it happens
A DOS program that drops DTR, a door hanging up on its caller or a full
board ending a call, used to go unnoticed: the line idled until the batch file behind the game
got around to its exit marker, which can be a long silence. The engine now watches the
modem-control line itself. The drop ends the call on the spot, with carrier-off mirrored back
into the machine first, so the program sees the NO CARRIER it expects while it saves on its way
out. The shipped test door grew a D command that drops DTR and proves the road end to
end.
Big files stop flirting with death on slow hosts
While a big file was still transferring, every read that landed on it
bought its own duplicate wire read as insurance: correct bytes, fatal arithmetic. A program
loading its overlay file issues hundreds of small sequential reads, and each one queued a wasted
duplicate on the single request lane until the transfer itself was starving behind them; past
DOS's half-second patience, the game crashed. Reads near the transfer's frontier now simply ride
it, and only a genuine seek far into untransferred territory buys a targeted read, one at a
time. Nothing got slower; the flood is gone.
Smaller door-engine notes
- The boot floppy retries its network attach. EtherDFS used to get exactly one shot at
finding the board's drive; a briefly throttled host at that instant meant a dead boot. Three
tries now, each re-checking the drive first.
- Door manifests take path globs. The static and session lists still speak plain DOS
masks, and now also forward-slash paths:
DATA/SAVE*.* pins one directory,
** crosses directories. Session trees work too, so directories a game creates
inside one live in the caller's tab and per-node scratch never touches the wire.
- Deaf input can be caught in the act. For the rare report of a session that stops
hearing keys, the engine keeps a receive witness (bytes handed to the machine, bytes it spoke
back, and the machine's undrained input queue) and with diagnostics on, a byte sitting unread
is called out in the browser console.
Upgrading
Overlay-upload the release over your existing board; data/
is untouched and there are no database changes in this release. The refreshed boot floppy and
client ride the version stamp, so browsers pick them up on their own. Existing door manifests
keep working unchanged; the new path globs are purely additive.
1.7.2 · August 25, 2026
Daily maintenance for DOS doors
1.7.2 brings daily maintenance to DOS doors and repairs the way a
door's first entry of the day treated data kept in subdirectories. Upgrading from 1.7.0 or
1.7.1 is a plain overlay upload.
New: daily maintenance for DOS doors
Some doors expect a maintenance program to run once a day. TradeWars
2002's EXTERN is not optional; Usurper's daily sweep matters too. A door's
dosdoor.json may now name it:
"maintenance": "EXTERN MULTITASK=NO"
The board cannot run DOS itself, so the clock arms the duty and a
machine runs it, the way 1993 did it: the first caller entering the door alone after board
midnight runs the command on the way in, sees it happen, and the game starts when it ends. The
board stamps the day the moment the run completes, so exactly one entry a day pays the toll,
and a run abandoned by a closed tab is retried by the next solo entry.
- The console can run it any time. The maintenance page for a door that names the
command grows a Run the daily maintenance button: same command, on that screen, and it stamps
the day so callers skip it. The page also shows when maintenance last completed.
- The log watches the calendar. If a door goes more than a day without a completed run
because nobody entered alone, the nightly tick puts one line in the SysOp log saying so and
naming both remedies.
- Nothing changes without the field. Doors whose manifest has no maintenance line
behave exactly as before, end to end.
The TradeWars 2002 package on this site now
ships the field, so EXTERN stops being a SysOp chore.
Bug fixes
- Doors that keep their data in a subdirectory no longer die or half-run their
first-of-day maintenance. The pre-entry transfer used to warm only the door's root
folder, so a game sweeping its DATA directory (Usurper, first login of the day) read every
file cold over the wire, and one slow-host burst mid-sweep tore a file or crashed the door at
the caller's feet. Worse, a burst landing on the directory listing itself handed DOS "no
files": the sweep finished in a blink having swept nothing, and the game stamped the day as
maintained. The transfer now warms one level of subdirectories, and the engine remembers each
directory's last full listing, answering repeat listings locally while nothing has changed
and serving the last known view if the wire ever eats a listing whole.
- The console maintenance page shows the door's line. A door game run by hand there
talks on the serial line, exactly as it does for a caller, and the page used to show only the
machine's own DOS screen: the game looked like it was doing nothing. The page now has two
screens side by side, the machine's own and the door's line (a real terminal that also answers
the door's ANSI probes), and keys go to whichever screen was clicked last. Config tools keep
working exactly as before.
- With diagnostics on, the door's DOS screen now stays up after every exit, not only
after error exits, for half a minute or until clicked. A door that dies young after one
keypress used to read as a short normal visit, and the one screen naming the error vanished
with the teardown.
Upgrading
Overlay-upload the release over your existing board; the
data/ folder is untouched. The first page hit adds two small columns to the DOS
door table (the maintenance day and its lease); the step is additive and safe to re-run. To give
an installed door a daily command, add the maintenance line to its dosdoor.json and
press Scan on the DOS Doors page.
1.7.1 · August 24, 2026
A repair release for the DOS doors
1.7.1 fixes the DOS door system that shipped in 1.7.0. If your board
runs 1.7.0, upgrade: the bug it fixes hits every caller whose browser has already visited a
door once.
Bug fixes
- DOS doors no longer die on entry once the browser has warmed up. 1.7.0 started the
DOS machine the moment the emulator was ready. On a first visit that was fine, but 1.7.0 also
taught the browser to cache the emulator, so on the next entry the machine was ready in a
blink: FreeDOS reached the game while the game files were still transferring, the two fought
over the line, and on real shared hosting the game's first reads timed out. The caller was
dumped back at the menu seconds after entering, TradeWars 2002 and LORD both, on every
browser, while an incognito window (nothing cached, machine loads slowly, transfer wins) kept
working and made the whole thing look haunted. The machine now waits for the transfer to
finish before it boots, the ordering that was proven in the field before the release. Entries
stay quick: the real 1.7.0 speedups, remembering a door's files between visits and caching the
emulator for a year, are untouched, so on a warm door the wait is a couple of small
checks.
- A door that dies no longer floods the SysOp log or scribbles on the menu. When a door
ended while its files were still coming, the transfer kept running against the seat the door
had just given up. Every request wrote a "Token mismatch" security line, many a second; the
files it never finished were announced as "Part of the game would not transfer"; and its
progress dots and that red warning printed over the menu screen, leaving stray color codes in
the middle of the art. Teardown now stops every transfer loop before its next request. After a
door closes, not one request goes out and not one character is printed, whatever the door died
of.
Upgrading
Overlay-upload the release over your existing board; the
data/ folder is untouched and there is no schema change. Callers pick the fix up on
their next page load. Nobody needs to clear caches or site data: the fixed scripts carry new
version stamps, and the files a browser remembered are checked against the board before they are
trusted.
1.7.0 · August 24, 2026
The DOS doors run, and your old board comes with you
The headline: real DOS doors, in the caller's browser
The games that made a BBS a place to be, LORD and its whole generation,
were DOS programs. Every modern way to run them parks a telnet server next to a DOSBox install
and asks the SysOp to babysit both. ATDT 1.7.0 does it the ATDT way instead: nothing DOS runs
on the server. When a caller opens a DOS door, their own browser boots a small FreeDOS
machine in about two seconds, the door's screen rides the caller's terminal like any other
screen, and the game's files live on the board, served one read and one write at a time. The
caller needs a current browser and nothing else. The server needs PHP, exactly as before.
- Install like it is 1993, run like it is 2026. A door is a folder dropped into
dosdoors/ off the BBS root: the game's own files in files/, one
dosdoor.json beside them naming the command line, the drop file format, and
which files never change. Scan it from the new DOS Doors console page, put a DOSDOOR item on
a menu, done. A shipped test door proves the whole pipeline before any real game is
installed.
- A real shared drive, not a copy of one. Inside DOS the game directory is drive D:,
served over a network redirector, the same trick a Novell LAN pulled. Multiple callers play
the same game world at once: every write is serialized under a lock, DOS record locking
arbitrates through the board exactly like SHARE on a LAN, and a generation counter tells every
node's cache the moment anything changes.
- Drop files done properly. DOOR.SYS (GAP), DORINFO1.DEF and CHAIN.TXT, generated per
caller per entry with the handle, level, node and daily minutes, planted where only that
caller's machine can see them.
- The terminal stays the terminal. Door output is CP437 with ANSI, so it lands in the
same screen, same font, same 16 colors as the rest of the board. Cursor-position reports are
answered, ANSI music is swallowed instead of printed, and arrow keys arrive as the sequences
doors expect. Ctrl+] three times hangs up the door: the game sees carrier drop and gets a
moment to save, the way a real hangup worked.
- The SysOp holds the keys. The whole system sits behind a master switch, off by
default. Per door: enable, ACS, node cap, daily minutes, a diagnostics ring that shows which
file operations are slow, live seats with force disconnect, and a typed-name Reset game state
that starts the world over.
- Configure the door where it lives. Every door row has a maintain page: it boots the
same FreeDOS machine in your own tab, on the live game drive, with the machine's screen and
keyboard facing you. Type LORDCFG.EXE and drive it; when the program exits, a real DOS prompt
on D:\ is waiting for DIR, COPY, TYPE START.BAT, or an installer aimed at D:\. No DOSBox
detour.
- Hardened against shared hosting. File transfers ride in filter-sized pieces with
retries and a per-file fallback, because some hosts eat oversized replies whole. Batch files
that lost their carriage returns to an ASCII-mode upload, which DOS abandons after one line
without a word, are repaired at seed time and flagged in the Files panel.
The full chapter covers installation
and the console page. Ready-made packages for The Pit, Arrowbridge
II, Drakeville and TradeWars 2002 are on the site, along with known quirks for LORD and a full
guide for Usurper.
The second headline: message import from legacy BBS systems
No other BBS package offers a migration path in. Every one of them
assumes you are starting from nothing or already running their software. ATDT 1.7.0 makes ATDT
the destination: a new console page, Import, reads the message history out of another
board and brings it into ATDT areas, with the areas, authors, dates, recipients and reply
threads intact.
- Every source a SysOp is likely to have. The packages people actually ran (Mystic,
Synchronet, ENiGMA 1/2, Talisman, Magicka, RemoteAccess, Telegard, QuickBBS, Maximus, EleBBS,
ProBoard, and WWIV by way of a QWK packet), the raw formats for those who know what they have
(JAM, Squish, Synchronet SMB, Hudson, FTS-1
*.msg, QWK, ENiGMA SQLite), and a
permanent third entry: the documented ATDT Import Format, a
zip of JSONL files any exporter can write. That last one covers the C64, Apple II, Atari and
homebrew boards no native parser will ever reach.
- Prove it before it commits. Six screens: pick the source, preview the parse with
exact counts, date ranges and three real messages rendered exactly as they will be stored,
map every source area onto a new or existing ATDT area, confirm behind a backed-up-data
checkbox, watch the chunked progress, and a permanent Import History page.
- Careful with the past. Everything is transcoded to the CP437 repertoire with
substitution counts reported (PETSCII ships its own lookup table). Dates convert through a
real timezone, with two digit years pivoting at 79. FTN kludge lines are stripped; tearlines
and origin lines stay, because callers saw them and they are part of the record. Literal
pipes are doubled so a 1987 message cannot change screen colors.
- Threading that cannot hurt you. Messages write in ascending date order so message
numbers follow chronology; orphan replies become thread roots, and reply cycles in damaged
bases are detected and broken.
- Nobody drowns. After an import, every existing caller's last-read pointers move past
the archive, and a seed watermark protects accounts created later.
- Undo that works. Every import is stamped with a batch id. Undo, gated behind typing
UNDO, deletes every message the batch wrote and removes any area it created that is now
empty. Imported authors are never matched to caller accounts: a 1991 handle colliding with a
2026 caller must not attribute someone else's words to a real person.
- Shared hosting safe. Imports run in supervised chunks from the console, no cron and
no daemon, pause when the page closes, and resume from Import History.
Tested at 60,000 messages across two formats, into both new and existing
areas, with the undo verified. The full chapter is here.
Smaller improvements
- The offline switch. For maintenance days: flip the board offline under Settings and
nobody can connect or log in, not even a SysOp account, until it flips back. New callers get a
notice in your own words and then the line drops. Callers already on stay on; a separate
Disconnect everyone now button hangs up every line at once.
- Home and End, said out loud. The message list jumps to the top or bottom with Home
and End, and the command line under the list now says so.
- Area descriptions earn their keep. The area picker paints the highlighted board's
description on its own quiet row as the highlight moves. A new
%AD code carries
the current area's description into theme strings, menus and art.
- Last call is yours to set. The console user editor can set a caller's last call date
on the board clock, or clear it to never. For the SysOp bringing in decades of history whose
callers should not all read as if they never called.
- Brackets in handles. Handles may carry
[ and ] now, a small
courtesy to the C64 crowd.
Bug fixes
- Long private letters page instead of truncating. The mail room used to cut a letter
off at the bottom of the screen. It now pages with N and P and a page indicator.
- Theme copies now offer every string. The strings editor used to list only the keys
present in the theme's own file, so a theme duplicated under an older release never showed the
strings added since. The editor now lists the complete catalog: your values where you
customized, the default marked inherited where you did not.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched. The first page hit climbs the schema ladder: new tables for
import batches and staging, new tables for DOS doors, sessions and locks, all additive only and
safe to re-run. If you keep theme copies, the console greets you once with the new-strings
notice.
1.6.5 · August 17, 2026
Rooms of their own
This release is about giving parts of your board their own message
life. A menu item can now point a message command at a specific board; a menu can keep its own
current area, separate from the rest of the system; and an area can step out of the general
list without giving up anything else. Build a door-game lounge with its own boards, a
language-split board with parallel message trees, a private co-SysOp wing, or an area picker
drawn entirely in your own ANSI: all of it from the menu designer, no code. And if you set none
of it up, nothing anywhere changes. Every new field ships blank, and blank means exactly the
board you already run.
Point a menu item at a board
The Read, Post and New scan items grew an optional
Area field in the menu designer. Set it and that one item acts on that one board, for
that press only. The caller's current area does not move, on that menu or anywhere else; reply,
quote and everything inside the reader behave exactly as they always have.
The classic use is a game lounge: a menu whose "Strategy board" reads
straight into SUZ_STRAT, a "Chronicles" item beside it, a post item, and the door itself.
Players talk shop without ever leaving the lounge or losing their place on the rest of the
board.
Targeting never bypasses access: an item aimed at a board the caller
cannot read shows the standard denial. An item aimed at a tag that no longer exists tells the
caller the board is gone and logs a warning naming the menu, the key and the tag. A mis-typed
item is a thirty-second fix, not a mystery.
Hand-built area lists, two flavors
Two new MODULE keys let a menu select the current area directly, and
between them they cover both shapes a hand-built picker can take.
- setarea stays on the menu. Put the board keys beside Read, Post and New scan on one
combined menu and the menu itself becomes the picker: press a number to switch boards, press
R to read, never leave the screen. This is the natural shape for a themed section, and it
works on a full-screen ANSI backdrop with hidden hotkeys just as well as on a generated
menu.
- setareaback picks and returns. Build a standalone area list as its own menu, reached
by GOTO from wherever your message commands live. Picking a board sets it and steps the
caller straight back to the menu they came from, exactly like the stock picker does. Draw it
in ANSI and you have replaced the system area list with your own.
Both keys require an area in the designer, both respect Read ACS like
everything else, and after either press the menu repaints in full, so a template showing
%AN or %MC names the new area immediately. With the filtered picker
below, that makes three interchangeable doors to the same mechanism: the system picker that
returns, the combined menu that stays, and your own picker that returns.
Sections with their own current area
Every menu's form gained a collapsed Area scope (advanced)
section. Leave it alone and the menu behaves as it always has. Give it a short name, such as DE
or LOUNGE, and that menu keeps its own current message area, remembered per caller
between calls, completely separate from the board's. Menus that share a name share the area; a
Default area picks where callers start, and their choice sticks per section.
A language-split board finally reads like one: a German section and an
English section, each with its own boards and its own sense of "where I was reading," while the
stock message menu carries on untouched. Inside a scoped menu, %AN and
%MC in a template speak for the section's own area, so "Area: %AN" on a section
menu names the right board.
A picker for one shelf
An Area change item can name a category: the picker then shows
just that shelf. Boards you unlisted still show inside it; you hand-picked that list, after
all. A category name that no longer matches falls back to the full list and logs one
warning.
Unlisted areas
Areas grew a Listed checkbox, checked by default. Uncheck it and
the area leaves the general area-change list, and changes nothing else. It still counts, still
opens from any item that names it, and still reports to the global new scan for anyone who
passes its Read ACS.
Unlisted is discovery, not security. A public-but-unlisted
lounge will announce itself in a caller's new scan. If you want a section genuinely private,
gate it with Read ACS; the edit form nudges you about exactly this when an unlisted area is
readable by everyone.
Tidy the public room
Every public chat line on the console's live wire now carries a delete
link. One click and a confirm removes that line from the room for good, with an audit line in
the SysOp log recording who said what. Pages and private SysOp traffic are working records; the
link never appears on them, and the guard refuses them outright.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched. The first page hit climbs the schema ladder:
- Four new columns and one small table appear: the Listed flag, the menu scope fields,
the item's second argument, and the per-section current-area store. All blank, all inert
until you use them.
- Nothing is copied or migrated. The board's existing current-area bookkeeping is not
touched, read or moved. A board that never opens the new fields runs byte-identically to
1.6.1.
- Housekeeping runs itself. Deleting an area that a menu item targets is refused with
a list of the referencing items; renaming a tag follows through everywhere; stale per-section
selections sweep on the daily tick.
- Theme copies get the one-time notice about two new denial strings, if you keep
copies; the shipped default theme already carries them.
1.6.1 · August 13, 2026
The bell follows you
A small release with a doorman's sensibilities: the application desk
learns which names are not welcome, a page rings the SysOp's own pocket instead of an empty
console, and the message boards stop marking things read that nobody actually read.
Prohibited names at the application desk
Settings › Access grew a prohibited-words list, one word
per line, with sysop already on it. A new caller's handle is refused if it
contains a listed word anywhere, in any case: put test on the list and Test,
Testicle and Youtestit are all turned away at the door. Nothing is retroactive; the list is
read only when a new application is typed, and every existing account keeps its name.
An applicant who tries three prohibited names in a row is done
applying: the board shows them the address they are calling from, notes that address in the
security log, and drops the line. Any clean attempt in between, even a malformed or taken one,
resets the count; the rule is three in a row, exactly as it reads. The refusal and the goodbye
are theme strings like everything else the caller sees
(nua.banned_handle, banned_bye, banned_ip), so a themed
board can word its own bouncer.
Pages reach your pocket
A caller paging the SysOp has always lit the console, but nobody sits
in the console all day. Settings grew a SysOp notifications card: enable it on a
browser, desktop or phone, and every page arrives as a real system push notification naming
who is calling, which node, and the reason they gave, whether or not the console is open
anywhere. Tap it and the console comes to you, ready to answer on their line.
- Standard Web Push, zero baggage. VAPID keys are minted by the board itself on first
use and the board talks directly to the browser's push service. No libraries, no third-party
accounts, no snippet of anyone else's JavaScript.
- Strictly opt-in. Exactly like outgoing mail: no browser enabled, no outside
connection is ever made. Enable as many browsers as you like, remove any of them from the
same card, and send yourself a test ring to hear what a page feels like.
- Never in a caller's way. Pushes are sent best-effort with short timeouts; a push
service having a bad day cannot slow the caller whose page is ringing. Dead subscriptions
prune themselves.
Browsers require HTTPS for push. Boards on plain HTTP keep the console
bell, and the card says so instead of failing quietly.
Only what you read is read
Message lists run newest-first, so a caller often opens a fresh reply
before an older message they have not seen. The read pointer used to leap straight over that
older message and silently mark it read: the reply was read, the message below it never was,
and the new-scan walked on by. The bookkeeping is honest now, and each message is marked read
when it is actually on the screen. The unread markers and the new-scan keep pointing at what
was skipped, and the pointer catches up on its own the moment the gap is walked. Nothing
changes in how reading feels; only the ledger stopped rounding up.
A quiet week no longer empties the chat room
The housekeeping cron used to sweep every chat row older than seven
days, the public room included, so a board with a slow week woke up to a blank room. The room
is the board's living room: it now keeps its newest 1,000 lines however old they are, and age
never empties it; only the overflow beyond the cap is swept. Transient wire traffic (page
requests, private SysOp lines and their hang-up markers) still expires after a week, exactly as
it should.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched. The first page hit climbs the schema ladder: two small tables
appear (individual read marks, and the SysOp's push subscriptions), the prohibited-words list
seeds itself with sysop (only when the setting has never existed, so a board that
deliberately emptied the list stays empty), and theme copies get the one-time notice about the
three new application-desk strings. The shipped default theme already carries them.
1.6.0 · August 10, 2026
Themes that travel, and a board that minds the line
Everything that changed from 1.5.5 to 1.6.0, in one place.
New features
- Themes travel as one file. Every theme on the Themes page has an Export link
that downloads the whole look as a single
.atdt-theme.json: strings, settings,
art bindings, and the ANSI art itself packed inside. The new Import a theme card takes
such a file and installs everything in one step. The art lands in the board's gallery, a
taken theme name is uniqued, and clashing art names are handled byte by byte: identical
pieces are shared rather than duplicated, different pieces are renamed with the theme's
bindings remapped to follow. An import can never overwrite art you already have. Built for
trading themes between boards, and for a theme shelf on the ATDT web site.
- Idle callers hang up. Anyone quiet for 30 minutes, at any screen including the login
matrix, is logged off with a polite note and NO CARRIER, and the node frees up. Idle means no
keypresses: an abandoned open tab cannot hold a line just by keeping the browser
connected. The minutes are adjustable in Settings (0 disables).
- Log off a caller from the console. Who's Online on the Dashboard grew a Log
off button per line. The caller sees "The SysOp has closed this line." and NO CARRIER;
the action asks first and lands in the admin log.
- Split-screen SysOp chat. Settings offers a second style for break-ins and answered
pages: the caller types in the top half of the screen, the SysOp's words fill the bottom
half, and a labeled rule divides them, a proper old-style sysop chat. Classic (one shared
scroll) remains the default; the console side is the same either way.
- The board has a line speed. A new Line speed setting (default 9600) is the
board's own baud: brand-new callers start there instead of at a hard-coded number, the
pre-login screen always types out at it, and the connect banner shows the matching CONNECT
9600, or CONNECT 14400 with the throttle off. Picking below 9600 earns a word of caution on
save: charming to modem veterans, possibly "broken" to everyone else.
%BD, a new MCI code. Expands to the viewer's connection speed, their
own throttle if they set one, otherwise the board's line speed, and reads FAST when the
throttle is off. Works everywhere MCI works, ANSI art included.
- The message boards, in the console. Community grew a Message boards tab
listing every category and board exactly as callers see them, with live counts. Open any
message to edit its subject, body, or date and time stamp, or to delete it (soft, same as
caller-side deletes). The author and the message's place in the reply tree are facts of the
record and never change. Private mail is excluded at the query level: the console does not
read anyone's letters.
- Theme upgrades speak up. Standing rule, now permanent policy: a release only ever
updates the shipped default theme, never your copies. Every release that adds or rewords
caller-facing strings now arms a one-time notice on the console dashboard listing exactly
which strings changed; a board that skipped versions sees the union of everything it missed.
This release's list: the matrix reset strings and the split-chat labels.
- The Bulletins hint in the console no longer claims callers read them under [B]; that key is
yours to remap in the menu designer.
Bug fixes
- Changing message areas ignored the throttle. Entering a message area painted the
whole screen instantly regardless of connection speed: every screen that takes line input
armed its prompt by fast-forwarding the reveal. Prompts now wait their turn, the screen types
out at the wire speed, and the input field arms when it finishes. A keypress still
fast-forwards, as always.
- The goodbye screen ignored the throttle. Logging off painted the farewell, custom
ANSI or default, instantly and dropped the line. The goodbye now reveals at the caller's
speed and the line waits for it to finish before NO CARRIER.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched. The first page hit climbs the schema ladder (sessions gain
idle-tracking and hang-up columns). If you keep theme copies, the console greets you once with
the new-strings notice described above.
1.5.5 · August 4, 2026
The editor release
Big ANSI letters without drawing them by hand, a recolor tool, visual
move and copy, a gallery you can browse, and doors that can post their own announcements to a
message board.
New features
- ANSI letter fonts, TheDraw style. The editor grows a Font tool: pick a font,
click the canvas, and type. Big letters land as ANSI, no more drawing every welcome-screen
letter by hand. Four fonts ship (Block, Block Wide, Block Shadow, Small), covering A to Z and
0 to 9 and stamping in your current ink. The font library (Fonts... next to the tool)
is its own little editor: draw your own sets glyph by glyph, up to 16 by 8 cells each, colors
and all, and fonts you draw stamp exactly as drawn. Stored under
data/fonts/.
- Recolor without retyping. A new Recolor tool (C) repaints what is already on
the canvas with the current ink and leaves the characters alone; with a selection, the new
Tint button recolors the whole block at once.
- Move and Copy are visual now. Move used to be a blind cut-then-click; now the
selection visibly lifts off the canvas and rides the mouse (or the arrow keys, with Shift
moving by five). Enter or a click sets it down, Esc puts it back untouched, and the whole
move is a single undo step. Copy floats the same way.
- Clear canvas. A Clear button blanks the whole canvas. It asks first, and Undo can
still bring the work back.
- The Gallery page. A new console page shows every piece on the shelf with a real
preview, ten to a page, with an "Open in editor" button on each card. The dropdowns stay for
small boards; this is for the big ones.
- Message boards by arrow key. Callers can now select the message board they want to
view with the arrow keys plus Enter.
- Doors can make announcements. A door's daily cron hook and its console panel can post
a real message into a message area of the SysOp's choosing, under the SysOp's name, and read
recent board rumors for flavor. Both calls are mediated by the engine, so doors still never
touch a board table. Built for games that publish on their own clock, and fully backward
compatible with existing doors. See the Door API.
Bug fixes
- Goodbye art no longer loses its top rows. The signoff screen painted its art without
clearing first, so the picture flowed from wherever the logoff prompt had left the cursor and
scrolled its own first line or two off the top. Goodbye art now gets a clean screen like every
other art display, and
+++ NO CARRIER prints on row 25 instead of pushing the
picture up, so even a full-height piece keeps every row.
%LC shows the last caller again, not you. The token read the newest
logged call, which after login is the caller's own, so the welcome line greeted everyone with
their own name. It now skips the current session's call; calling twice in a row still counts
your previous call.
- Bulletins list newest first, on the board and in the console. A SysOp's manual sort
still rules, and the logon tour for new callers still walks history oldest-first, as
designed.
- Descenders survive the editor. Letters like y and g lost their tails in the ANSI
editor (the board always rendered them right): resizing the editor canvas silently reset the
text baseline, pushing descenders into the next row's repaint. The painter now pins its
baseline on every draw.
- "Generated" that would not come back. Picking the generated layout for a menu looked
broken when a per-level variant kept overriding it, a state easy to set up and hard to see.
The menu designer now says so next to the backdrop picker, and saving "generated" over live
variants spells it out in the flash message, with the count.
- SysOp chat and break-in actually work. It did not work at all half of the time, and
the other half it did not work as intended. Now it does.
- More than eight message boards display. Previously, if you had more than eight
message boards, there was no way to scroll the list. Now you can.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched and there is no schema change. data/fonts/ appears
the first time a font is saved.
1.5.0 · August 1, 2026
The mail release
ATDT can now, entirely at your option, send email: password-reset links
for callers and private letters to the SysOp. Switched off (the default), the board keeps
making no outside connections at all, exactly as before.
New features
- Outgoing mail (optional). A new card in Settings lets the board send email through a
mailbox you own (SMTP) or the hosting company's mail system. Send-only: the board never reads
a mailbox. A one-click test message proves the setup, and every send lands in the events
log.
- Password reset by email. With mail on, a caller who fumbles their password can press
R at the login screen. If the handle has an email on file, a single-use reset
link (20-minute clock) goes out, leading to a small browser page that sets a new password.
The board answers the same sentence whether or not the account exists, and SysOp accounts are
excluded on purpose.
- Email on the account. New applicants get an optional email question, existing callers
without one get a one-line ask at logon (ENTER skips it), and the caller settings screen can
set, change, or clear it any time. Never verified, never shown to other callers; only the
SysOp sees it, and it exists for password resets and nothing else.
- Email the SysOp. A new EMAILSYSOP menu action gives callers a private line off the
board: subject plus a full-screen letter, sent from the board's account to the address the
menu item names, with the caller's own email as Reply-To. One letter per caller per day; the
item hides itself while mail is off.
- A caller guide to the codes. A new HELP menu action shows a two-page guide: every
pipe color code painted in its own color, then the full MCI variable table with live
examples.
- The mail room shows sent letters. Press
S in the mail room to flip
between your inbox and the letters you have sent, with who they went to and a full read-back
view.
Bug fixes
- SysOp, spelled properly. The console now writes SysOp with the capital S and O
everywhere: top bar, footer, login page, and every label in between.
- ART picker. The ART menu action in the menu designer offers a dropdown of gallery
pieces instead of a type-the-name field, matching every other action.
- Full-width rumors and oneliners. The entry prompt sits on its own row, so the whole
79 columns fit and nothing is cut off mid-thought.
- The rumor wall keeps its secret. The caller-side rumor screen shows a count and takes
submissions but never lists the pile, so the one-random-rumor logon surprise stays a surprise.
The SysOp reads the whole list in the console's Community desk.
- Every unread bulletin at logon. Callers see every bulletin they have not read yet,
oldest first, not just the latest; a brand-new caller walks the whole backlog once. Each
account keeps its own high-water mark, so nothing replays, and editing a bulletin does not
re-greet callers who already saw it.
- The auto-message wall is caller-editable again. The menu item's ACS is the one and
only gate, as designed. The console's Community desk also gains an Auto-message tab showing
the current wall, who painted it and when, with an editor of its own.
Upgrading
Overlay-upload the release over your existing board;
data/ is untouched. The first page hit migrates the database automatically (new
per-account email, bulletin bookmark, and reset fields). Existing callers' bulletin marks start
at the current top, so nobody is greeted by years of old bulletins. The "Allow pipe colors in
caller content" switch now ships on for brand-new installs; an upgrading board keeps its
earlier choice. All mail features stay dormant until you configure and enable outgoing mail in
Settings.
1.1.1 · July 28, 2026
MCI variables everywhere, including inside the art
New features
- MCI variables work everywhere. The live board codes (
%HN for the
handle, %BN for the board name, %TM for the time, and the rest of
Appendix B in the manual) now expand in every place the board shows text, whoever typed them,
SysOp or caller: message and private mail bodies and subjects, bulletin bodies, oneliners,
rumors, the auto-message, chat, BBS-list notes, and the broadcast banner. Each reader sees
their own values: a message that says "hi %HN" greets every reader by name, and a broadcast
can promise "back at %TM". Unknown %-pairs pass through untouched, and expansion happens at
display time only, so the stored text keeps the codes.
- MCI works inside ANSI art. Codes drawn into any
.ans piece expand when
the art is shown: the connect, logon and goodbye screens, menu backdrops and per-level
variants, ART menu items, and art bulletins. Draw "WELCOME TO %BN, %HN" into a logon screen
and it greets every caller by name. On the connect screen, before anyone logs in,
%HN reads "caller". A substituted value shifts the rest of its row, so leave
drawing room around the code.
Bug fixes
- A pipe character typed into a message or mail subject no longer displays doubled in the
reader and mail-room headers; it shows single, exactly as typed.
1.1.0 · July 28, 2026
Copy and paste, an art gallery, and doors that behave like everything else
New features
- Copy and paste in the terminal. Paste with
Ctrl+V, Cmd+V,
or the context menu: the text types into whatever accepts typing, whether that is a prompt
line or the full-screen message editor, where pasted newlines become real line breaks. Drag
a rectangle anywhere on the screen and it lands on the clipboard at mouse release, the
classic terminal way.
- Board phone number. Settings › Identity takes a Board number. The connect
ceremony dials it and
%PH carries it into any theme string. Leave it blank for
the classic number derived from the board name.
- A selectable default theme. Settings › Look and feel picks the theme every
caller sees. Individual callers can still be pinned to a specific theme on the Users page,
where "(board default)" now follows the Settings choice. No more applying a new look account
by account.
- The art gallery. The ANSI editor saves to one board-wide gallery in
data/art/ instead of per-theme slots. Everywhere art can appear picks a piece
from the same shelf by name: theme connect, logon and goodbye bindings with live previews on
the Themes page, menu backdrops and per-level variants, ANSI bulletins, and ART menu items.
Import and export are unchanged, and art from older boards moves into the gallery
automatically on upgrade.
- IP bans with a proper goodbye. Settings › Access takes a ban list, either
exact addresses or
prefix* wildcards. A banned caller gets a themed refusal, the
connect.banned string, editable like any other, before the connect ceremony even
starts. A ban landing mid-call drops the line on the next keystroke.
- The SysOp console footer now shows the running ATDT version.
Bug fixes
- Doors are ordinary menu items. Any menu named DOORS used to synthesize its door
entries at render time, invisible to the menu designer and impossible to edit. Door items are
now real menu items: seeded for the shipped games, added automatically when a scan registers
a new door, and renameable, reorderable and removable like anything else. Existing boards
gain the items on upgrade.
- Chat lines wrap instead of vanishing. A long chat line used to clip at the right
edge. It now word-wraps onto up to three display rows, colors carried across the fold, so
every typed character shows. Public chat and the private SysOp line both.
- One handle, one node. The same account can no longer be logged in on two nodes at
once. A second login is refused with a themed message while the first is live, and a dropped
connection frees the handle within about 90 seconds.
- The default theme is truly read-only. Saving art used to silently make the shipped
default theme editable, strings included, and arm a Remove button that could
destroy SysOp-drawn art. The default is now the board's permanent fallback: never editable,
never removable, regardless of what the editor or the test suite left on disk. Duplicate it
and edit the copy, then set the copy as the board default in Settings.
- Removed stale pre-release copy from the console's Doors page and the menu designer's action
list.
Upgrading
Overlay-upload the release over your existing board.
data/ is untouched and the first page hit migrates everything, including from
1.0.0 or any earlier schema. Skipped versions climb every rung of the ladder in one go, under a
lock, and the new steps are safe to re-run.
1.0.0 · July 25, 2026
Initial release
The whole board, finished and documented. Everything below shipped in the box.
- The terminal. 80 by 25 CP437 rendered with a real IBM VGA font, hotkey menus, line
prompts, a full-screen message editor, iCE color support, and an optional connect
ceremony.
- Messages. Areas grouped into categories, a threaded reader, new-scan across areas,
and private mail.
- Community. Bulletins, oneliners, rumors, a voting booth, the auto-message wall, a
BBS directory, user list, last callers and who's online.
- Chat. One public room with scrollback, page SysOp, SysOp break-in on a private
line, and timed broadcast banners.
- The console. Dashboard, users and access levels, access strings, a live menu
designer, themes, a full ANSI editor, the community desk, door registry, and three logs.
- Doors. HILO and Star Merchant, plus the version 1 Door API with private tables, a
key/value store, cron and admin hooks, and a JSON drop file.
- Operations. A self-locking web installer, SQLite or MySQL, real cron or pseudo-cron,
and single-folder backups.