ATDT Demo board online

Documentation

The SysOp's Manual

Every screen, every option, every switch, as actually shipped. Installation, the whole console, the caller experience you are curating, and how to get your board back when something goes wrong.

ATDT BBS 1.7.4 · September 2, 2026

Chapter 01

#Welcome

ATDT is a complete bulletin board system that runs on ordinary shared web hosting. Callers get an authentic CP437 terminal in the browser: ANSI art, hotkey menus, message bases, live chat, and door games. You get a modern web console to run all of it.

Everything lives in one folder. The board is the atdt/ directory you uploaded; all of its data (database, configuration, custom themes, door saves) lives in data/ inside it. There is no daemon, no build step, and nothing to install on the server beyond PHP itself.

About this edition. Where the shipped board goes beyond the original specification (SysOp break-in chat, ANSI replacements for generated menus, message area categories, outgoing mail and password resets, ANSI letter fonts, theme sharing, and more), this manual documents the shipped behavior.

Vocabulary

CallerA user of the board, connected through the terminal page.
SysOpYou. System operator: level 255, console access.
NodeOne live connection. Two browser tabs are two nodes.
The matrixThe pre-login screen where callers log in or apply.
AreaOne message base: a board within the board.
CategoryA named shelf that groups areas in the area list.
DoorA game or utility that runs inside the board.
ACSAccess Control String: who may see or do a thing.
Pipe codesInline color codes like |12 that color text.
ScopeA menu's own current message area, separate from the board's. Menus that declare the same scope name share one; menus that declare none use the board's current area, as ever. New in 1.6.5.
ConsoleThe web admin at /admin/. Callers never see it.
Chapter 02

#Installing the board

Requirements

PHP 8.1 or newer Extensions pdo · mbstring · json · openssl · session Database pdo_sqlite (recommended) or pdo_mysql Hosting a writable web directory · no shell access · cron optional

The installer checks all of this on its first screen and explains anything missing. On a too-old PHP it shows a friendly page instead of an error.

The install wizard

  • Upload the contents of the atdt/ folder to your web space. The web root and a subdirectory (for example /bbs/) both work.
  • Visit https://your-site.example/install.php. The environment check runs; continue.
  • Pick the database. SQLite needs nothing and is right for almost everyone; the database file gets a randomized name inside data/. MySQL asks for host, port, database name, user and password, with a test-connection button.
  • Board identity: board name (up to 60 characters), SysOp handle (3 to 20 characters: letters, digits, space, period, underscore, hyphen), SysOp password (minimum 8 characters, typed twice), board timezone (US zones listed first; this is the clock callers see and the boundary for the daily tick), and base URL (auto-detected; correct it if your board's public address differs).
  • Done. The installer prints your cron line (chapter 17) and links to the board and the console.
Note. You may delete install.php if you like, but you do not have to. It locks itself and refuses to run while data/config.php exists.

Reinstalling

To wipe and start over, delete data/config.php (or the whole data/ folder) and visit install.php again. To upgrade in place instead, see chapter 19.

Chapter 03

#Your first hour as SysOp

The console lives at /admin/. Log in with the SysOp handle and password from the wizard. Only level 255 accounts may enter; wrong passwords are throttled (five tries per 15 minutes, lockouts logged); every session rides a CSRF-protected cookie.

A sensible first hour:

  • Open the board in another tab and look around as a caller. The seeded board has two areas on a "Main Boards" shelf, a welcome bulletin, and two doors.
  • Settings: confirm board name, timezone, base URL. Pick your new-user policy.
  • Community: rewrite the welcome bulletin in your own voice.
  • Areas: rename the starter areas or build your own layout with categories.
  • Themes / Editor: draw or import a logon screen.
  • Leave the first oneliner. Boards feel alive when the walls have writing on them.
Chapter 04

#What callers see

The terminal page is an 80 by 25 CP437 screen rendered with a real IBM VGA font. Menus respond to single hotkeys, prompts take a line of input, and a full-screen editor opens for message writing.

The clipboard works the terminal way: paste (Ctrl+V, Cmd+V, or the context menu) types into whatever accepts typing, a prompt line or the message editor, where pasted newlines become real line breaks. Drag-selecting any rectangle of the screen copies its text at mouse release, PuTTY style.

Keys echo (1.7.4). Press a hotkey and the character you typed 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.

The cursor (1.7.3). The terminal keeps a classic blinking underscore at the resting position of every hotkey prompt: menus, pause lines, pagers, the whole logon tour. Before this, 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. It is drawn over the screen and 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.

The matrix and new users

Before login: L to log in, A to apply, G to log off. Applications ask for handle, password, location, your custom question, and an optional email address; ENTER skips it. What happens next follows your new-user policy: approve (waits for you; the dashboard shows pending), auto (activates instantly), closed (no applications).

With outgoing mail configured (chapter 6), the matrix also answers R for a forgotten password. Since 1.6.0 it takes one press: right after a failed login, R sends the reset for the handle just tried, with no retyping. Pressed cold, it opens a small PASSWORD RESET screen asking "Reset for:" instead of bouncing back to the login line. Either way, if the account has an email on file, a single-use reset link (20-minute clock) goes out. The matrix answers the same sentence whether or not the account exists, one link per 15 minutes per account, and SysOp-level accounts are excluded on purpose (a SysOp handle is told so in as many words, so nobody waits on a letter that will never come). With mail off, R is not a key.

Nobody can park at the matrix, either: the idle hang-up (chapter 6) applies before login the same as after, so an abandoned tab stops holding a node.

The post-login sequence

The order is yours as of 1.7.3. 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 MAIN. Stops with nothing to say still skip themselves, as before, and two courtesies keep their seats whatever you arrange: the one-time email ask for an account with no address on file, and the mail check when letters are waiting. A board that never touches the setting runs the classic order below, unchanged.

Connect banner (optional modem ceremony; since 1.6.0 the CONNECT number matches the board's Line speed, CONNECT 9600 out of the box or CONNECT 14400 with the throttle off), logon art, a one-line email ask for accounts without one (ENTER skips), every unread bulletin oldest-first (a brand-new caller walks the whole history once; edits do not re-greet), the auto-message wall, a random rumor, mail check, last callers, then the MAIN menu. Any key advances.

The default menu map

KeyWhere
MMessage menu. Read, post, new scan, change area, mailbox.
CChat. The live room, everyone together.
DDoor games. HILO and Star Merchant.
IInfo desk. BBS list, board stats, bulletins.
PPeople. User list, last callers, who's online.
OOneliners. The graffiti wall.
BBulletins. SysOp announcements.
YYour settings. Bell, connection speed, password.
GGoodbye. Log off, with confirmation.

Every menu, item and hotkey is editable in the menu designer.

Caller-side settings

Each caller gets a terminal bell toggle, a nostalgic connection-speed throttle (300, 1200, 2400 or 9600 baud, or off; keypresses drain the buffer instantly), a password change, and an [E]mail row to set, change or clear the address on their account. The mail room also answers S to flip between the inbox and the letters they have sent.

Two 1.6.0 notes on the throttle: new accounts start at the board's Line speed (chapter 6) instead of a hard-coded number, and the typing-out now genuinely covers everything. Changing message areas and the goodbye screen used to paint instantly; both now reveal at the wire speed like the rest of the board, and the line waits for the farewell to finish before dropping carrier.

Read marks are honest (1.6.1): because lists run newest-first, a caller often opens a fresh reply before an older message they have not seen. The read pointer used to leap over the older one and mark it read on the way past. Now each message is marked read when it is actually on the screen, the unread markers and the new-scan keep pointing at whatever was skipped, and the pointer catches up by itself once the gap is walked. Reading feels the same; the ledger simply stopped rounding up.

The message list (1.6.0): threads sort by their date, newest first, with replies always nested beneath their thread. Because the sort reads the date, a timestamp fixed from the console re-files the thread automatically. S in the list flips to oldest-first and the choice sticks to the account; unread messages are caught either way by the new-scan. List dates show the year. New in 1.7.0: Home and End jump to the top and the bottom of the list, and the command line under the list says so. Sorting keeps your place, and one press of Home puts you back at the top.

The area picker names what it highlights (1.7.0). As the highlight moves, the picker paints the highlighted board's description on its own quiet row. Boards that never filled a description in look exactly as before.

Long letters page (1.7.0). 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.

Chapter 05

#The Dashboard

The console home page. Everything urgent surfaces here.

  • Stat cards: calls today and ever; messages today; pending callers (with inline approve when your policy is approve); cron health in minutes since the last tick (a dash means it never ran).
  • Who is online: every live node with handle, activity and idle time, plus three buttons per caller. Join chat drops you into the public room; Break in opens a private line to that caller (chapter 14); Log off (new in 1.6.0) hangs up that line. The caller sees "The SysOp has closed this line." and NO CARRIER, the node frees immediately, and the action lands in the admin log. It asks before it fires, and the line leaves the list the moment you confirm.
  • The chat panel mirrors the room without you holding a node. The target selector aims your words: everyone in the public chat room, or a private line to one node. A banner above the box always shows where the next line goes, and a caller's page arrives with the form pre-aimed.
  • Broadcast: type a message, pick minutes, and every connected caller sees it as a banner above their screen, whatever they are doing. Separate from chat; never lands in room history.
Chapter 06

#Settings, every field

Identity

Board nameTerminal title, banners, %BN in theme strings.
Base URLPublic address; used in generated links and cron advice.
Board numberWhat the connect ceremony dials; also %PH in theme strings. Blank keeps the classic number derived from the board name.
Board timezoneThe clock callers see everywhere; the daily-tick boundary. Storage stays UTC.

Access

Max nodesSimultaneous callers (default 10). Past the cap: a busy screen, like a full modem bank.
New user policyapprove / auto / closed.
New user questionYour custom application question; answers land in the caller's note field.
BBS list additionsACS for who may add directory entries (blank = everyone, v = validated). Viewing is always open.
Banned addressesOne per line: an exact IP, a prefix ending in * (203.0.113.*), or a # comment. A banned caller gets the connect.banned theme string instead of a dial tone, before any session exists. A ban landing mid-call drops the line on the next keystroke.
DOS doorsNew in 1.7.0. The master switch for running original DOS door games (chapter 21). Off by default, and off means no console page, no menu action, and an API that answers 404: callers cannot tell the feature exists.
Board offlineNew in 1.7.0. For maintenance days. Nobody can connect or log in, not even a SysOp account, until it flips back. New callers get a notice in your own words (pipe colors welcome; a stock line covers a blank box) and then the line drops. Callers already on stay on; a separate Disconnect everyone now button hangs up every line at once when the work needs the board empty. Every console page shows a reminder while the switch is on.
Prohibited wordsNew in 1.6.1. One word per line; sysop ships on the list. A new application's handle is refused if it contains any listed word anywhere, in any case: put test on the list and Test, Testicle and Youtestit are all turned away. Nothing is retroactive, since the list is read only when a new handle is typed, so existing accounts keep their names.

Three prohibited names in a row ends the application: the board shows the caller the address they are calling from, notes it in the security log, and drops the line. Any clean attempt in between, even a malformed or already-taken one, resets the count. The refusal and the goodbye are theme strings like everything else (nua.banned_handle, nua.banned_bye, nua.banned_ip), so a themed board words its own bouncer.

One more access rule needs no switch: one handle, one node. A caller already on the line cannot log the same account in on a second node; a dropped browser frees its handle within about 90 seconds.

Display

iCE colorsBright backgrounds instead of blinking text. On if your art uses them.
Connect ceremonyThe fake modem handshake on connect. Pure theater.
Allow user colorCallers may color their text with pipe codes in messages, mail, chat, oneliners, rumors and the auto-message. Off shows codes as typed.
Default themeThe theme every caller sees unless a specific one is set on their account (Users page). The everyday flow: duplicate default on the Themes page, edit the copy, pick it here.
The logon tourNew in 1.7.3. The order of the cards between the password and the main menu: welcome screen, unread bulletins, auto-message, rumor, last 10 callers. Give each stop a position or turn it off. Everything off means a caller lands straight at MAIN. The email ask and the mail check always keep their seats.
Line speedNew in 1.6.0. The board's default baud: 300, 1200, 2400, 9600, or "No throttle (CONNECT 14400)". New callers start here, the pre-login screen always types out at it, and the CONNECT banner shows the matching number. Default 9600. Dropping below that is charming to modem veterans and can read as broken to everyone else; the save reminds you.
Idle hang-upNew in 1.6.0. Minutes of caller silence before the board hangs up the line and frees the node, measured on keypresses rather than the browser's background polling, so an abandoned open tab cannot hold a node. Applies at every screen, the matrix included. Default 30; 0 disables.
SysOp chat styleNew in 1.6.0. How break-ins and answered pages look on the caller's side: classic (one shared scroll) or split (the caller types in the top pane, your words fill the bottom, a labeled rule divides them). Default classic; the console side is the same either way.

Outgoing mail

Send-only email through a mailbox you own. The board never reads a mailbox, and with the switch off (the default) it makes no outside connections at all.

Outgoing mailThe master switch. Off hides every mail feature on the board.
Transportsmtp (host, port, STARTTLS or SSL, username, password) or the hosting company's PHP mail().
From addressWhat the letters are sent as; usually the mailbox you configured.
Send testProves the setup in one click; the result lands in the events log.

What it unlocks: password resets from the matrix (R), the EMAILSYSOP menu action (callers write you a letter; replies go to their own email via Reply-To, one per caller per day), and the email question at application and logon. Every send lands in the events log. Caller emails are never verified, never shown to other callers, and visible only in the Users drawer.

SysOp notifications

New in 1.6.1, and strictly opt-in in the same way outgoing mail is: with no browser enabled, the board makes no outside connection for this at all. Enable it on a browser, desktop or phone, and a caller's 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. Tapping it opens the console on their line, ready to answer.

  • Standard Web Push, nothing borrowed. The board mints its own VAPID keys on first use and talks straight to the browser's push service. No libraries, no third-party account, no other party's JavaScript on your console.
  • 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 go out best-effort with short timeouts, so a push service having a bad day cannot slow the caller whose page is ringing. Dead subscriptions prune themselves.
Push requires HTTPS, which is the browsers' rule, not the board's. A board on plain HTTP keeps the console bell and the card says so rather than failing quietly.

The cron key

The Settings page shows the exact cron line for cPanel and a button to mint a new key. A new key invalidates the old one immediately; update your cron entry to match.

Chapter 07

#Users and access

The list

Search by handle, filter by status, sort by any column; capped at 200 rows (narrow the search past that). Pending applications float up with one-click approve.

The edit drawer, field by field

Level0 to 255. New callers start at 10; 255 is SysOp (console access, passes every ACS).
FlagsTwenty-six checkboxes, A to Z. Meaning is yours; ACS tests them with fA and so on.
Statusactive / pending / locked / deleted (soft; the row stays).
LocationFree text, shown in the user list and last callers.
NotePrivate SysOp note; application answers land here.
EmailThe address password resets go to. Optional, never verified, never shown to callers; only you see it.
ThemeWhich theme this caller sees.
Last callNew in 1.7.0. 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.
New passwordType once to reset; blank leaves it alone.

The level ladder: 10 = fresh caller; 20 and up = yours to define; 100 = a handy co-SysOp line (s100); 255 = SysOp.

Deleting is always soft. The handle stays reserved. Login lockouts clear after 15 minutes and are recorded in the events log.
Chapter 08

#Access strings (ACS)

One tiny grammar controls visibility everywhere: areas (read and write separately), menu items, bulletins, voting questions, doors, menu backdrops. Blank always means everyone. Level 255 passes everything.

TokenPasses when
s50Level 50 or higher.
fACaller has flag A.
vAccount is validated (active).
!fZNOT: caller lacks flag Z.
s50fBSide by side = AND.
s50|fBPipe = OR.
(s50|fB)!fZParentheses group.

Recipes: v members only · s100 co-SysOps · fP flag-holders · s255 you alone.

A worked example

Access strings are easier to understand as a set than one at a time. Suppose fresh callers stay at level 10, trusted regulars get bumped to 50, your co-SysOp sits at 100, and flag P goes to anyone allowed in the private lounge.

AREA READ ACS WRITE ACS General (blank) v everyone reads, members post Announcements (blank) s255 everyone reads, only you post Regulars s50 s50 invisible below level 50 The Lounge fP fP invitation only, by flag Staff s100 s100 you and the co-SysOp

Notice what each choice buys you. A blank read ACS means the area shows for everyone including a pending application, which is usually right for a general board and never right for a private one. Write s255 makes a read-only announcements area without a separate feature for it. And because a failing caller never sees the line at all, the Lounge simply does not exist for anyone without flag P: there is nothing to ask you about.

Chapter 09

#Message areas and categories

Areas are the message bases. Categories are named shelves that group them: callers see each category as a header with its areas beneath, and the reader labels the area "Category / Area."

Categories

  • Add (name up to 30 characters), rename inline, reorder with arrows. The caller list follows this order exactly.
  • Delete: the category goes; its areas stay, loose. Nothing else is touched.
  • Areas without a category gather under "Other Boards" at the end. A board with no categories shows the plain flat list.

Areas, field by field

TagShort unique key, 2 to 12 characters (A to Z, digits, underscore), unique board-wide.
NameDisplay name, up to 40 characters.
DescriptionOne line under the name, up to 100 characters.
CategoryThe shelf it lists under, or none.
Read ACSWho sees the area at all.
Write ACSWho may post. Read-only announcements: write ACS s255.
ListedNew in 1.6.5. Checked by default. Unchecked, the area leaves the general area-change list and nothing else. See below.
  • Arrows reorder an area within its own category (the order callers see).
  • Delete refuses while the area holds messages; empty it first.
  • The private mail spool is plumbing; the console will not let you edit or delete it.

Listed and unlisted areas

Every area has a Listed checkbox, checked by default. Uncheck it and the area disappears from the general area-change list, and from nowhere else. That is the flag's entire job.

An unlisted area still:

  • counts its messages everywhere totals appear;
  • shows up in the global new scan for any caller who passes its Read ACS. A caller with access deserves to hear about mail waiting for them;
  • opens normally from any menu item that names it (chapter 10.4), from a category-filtered area change, or as a menu's default area;
  • keeps serving a caller who was already reading it when it went unlisted.
Unlisted is discovery, not security. A public-but-unlisted lounge will announce itself in the global new scan. If you want a section genuinely private, gate it with Read ACS; the unlisted flag only keeps it out of the general list. The edit form nudges you about exactly this if you uncheck Listed on an area with a blank Read ACS.
Chapter 11

#Themes

A theme is the board's wardrobe: every caller-visible string, plus which art gallery pieces dress the three big moments. The default theme is the board's permanent fallback and is never editable: not its strings, not its art. To change anything, Duplicate it and edit the copy; anything missing in your copy falls back to the built-in look, so you can never break the board permanently.

  • Duplicate: copy any theme into an editable one under data/themes/<name>.
  • Strings: every caller-facing string, grouped, with a live pipe-code preview. Saves write your strings.ini overlay.
  • Art: three bindings, connect (the pre-login screen), logon (the welcome), goodbye (the farewell). Each picks a piece from the art gallery, or "(generated default)" for the board's own drawing. Live previews render through the real terminal parser.
  • Delete: blocked for the board's current default theme and while any caller wears it; deleting a copy of a shipped theme lets the shipped version show through.
  • Export (1.6.0): every theme row but default has an Export link that downloads the whole look as one self-contained <name>.atdt-theme.json: strings, metadata, art bindings, and the art bytes themselves. Made for trading. The default theme is not exportable on purpose, since every board already ships it; duplicate it and export your copy.
  • Import a theme (1.6.0): the card at the bottom of the Themes page takes such a file and installs everything in one step. A taken theme name is uniqued (-2, -3 and so on). The art lands in the gallery with byte-level care: a piece identical to one already on the shelf is shared rather than duplicated, and a name clash with different bytes is renamed with the theme's bindings remapped to follow. An import can never overwrite art you already have, and the flash message says exactly what landed, what was shared and what was renamed.
  • Which theme callers get: the Default theme picker in Settings covers everyone at once. A specific caller can be given a different theme in their edit drawer on the Users page ("(board default)" means they follow the Settings choice). New accounts follow the board default.

The everyday loop: duplicate default, edit your copy, set it as the board default in Settings. Done; every caller sees it.

One standing rule, made permanent policy in 1.6.0: the board never edits your theme copies. When a release adds or rewords caller-facing strings, the shipped default gains them and your copies fall back to the new defaults until you edit them yourself. Nothing breaks; the new wording simply is not in your voice yet. Every such release now arms a one-time notice on the console dashboard listing exactly which strings changed, keyed to the release, and a board that skipped versions sees the union of every list it missed. "Got it" dismisses it for good.

The lists so far. 1.5.0: the mail-room pair (mail.pick, mail.pick_empty) and the settings prompt (set.prompt). 1.6.0: the matrix reset strings (matrix.reset_ask reworded; reset_note, reset_sent_for, reset_sysop new), the split-chat labels (sysopchat.split_top, split_bottom), and the message-list command bar (list.commands, which now offers S to flip the thread order). 1.6.1: the three application-desk strings (nua.banned_handle, nua.banned_bye, nua.banned_ip). 1.6.5: two new denial strings for targeted areas. 1.7.0: list.commands (it now mentions Home and End), nua.bad_handle (handles may carry [ and ] now, a small courtesy to the C64 crowd), and the new mail.read_more for the paged mail reader.
Theme copies now offer every string (1.7.0). 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, and emptying a field returns it to inheriting.

Goodbye art, one note (1.5.5): the farewell piece now always paints on a cleared screen and +++ NO CARRIER prints on row 25, so even a full-height goodbye keeps every row.

Chapter 12

#The ANSI editor and the art gallery

A full drawing program at Console › Editor: an 80 by 25 CP437 canvas rendered by the same engine callers see. Everything it saves lands in the art gallery, one board-wide shelf of .ans pieces under data/art/, and everywhere the board can wear art picks from that same shelf by name.

Live text in art: type an MCI code into a piece with the Text tool and it expands when the art is displayed. "WELCOME TO %BN, %HN" on a logon screen greets every caller by name (Appendix B lists the codes). The substituted value shifts the rest of that row, so leave drawing room to the right of the code.

Tools

Pencil (P)Stamp the current glyph in current colors.
Half-block (B)Paint 80x50-feel pixels; right-drag erases.
Text (T)Click and type.
Font (O)New in 1.5.5. Big ANSI letters, TheDraw style: pick a font, click, type.
Line (L)Drag a straight run.
Rectangle (R)Drag a border box.
Flood fill (F)Fill a region.
Recolor (C)New in 1.5.5. Repaint with the current ink; the characters stay put.
Select (S)Drag, then Copy / Move / Tint / Blank. New in 1.5.5: Move and Copy lift the block visibly, steer with mouse or arrows (Shift moves by five), Enter or click places, Esc puts it back.
  • Palette: 16 foregrounds, 8 backgrounds (16 with iCE colors on).
  • The glyph row holds the full CP437 set.
  • Undo Ctrl+Z, redo Ctrl+Y; zoom and grid on the toolbar; Clear blanks the canvas (it asks first, and Undo brings it back).
  • The canvas autosaves to your browser while you work.

Letter fonts

New in 1.5.5. The Font tool types words as large ANSI letters, the way TheDraw's .TDF fonts did. Four fonts ship (Block, Block Wide, Block Shadow, Small), covering A to Z and 0 to 9 and stamping in your current ink. Enter starts a new line, Backspace steps back, and letters wrap like a typewriter.

Fonts... opens the font library, a small editor of its own: draw your own set glyph by glyph (up to 16 wide by 8 tall, any colors, so your fonts stamp exactly as drawn), and it appears in the Font picker alongside the shipped four. Stored as JSON under data/fonts/; transparent cells leave whatever is under them alone.

The gallery

  • Open: pick any piece off the shelf and edit it.
  • Save to gallery: writes a real .ans with a SAUCE record under the name you give; anything bound to that name updates instantly.
  • Delete: takes a piece off the shelf; screens bound to it fall back to their generated look.
  • Import: upload any .ans (256 KB cap), including classic scene art with iCE backgrounds, then Save it to the gallery.
  • Export: download the exact bytes; PabloDraw and Moebius open them. Round trips are pixel-identical.
  • The Gallery page (1.5.5): Console › Gallery shows every piece with a rendered preview, ten to a page, each with an Open-in-editor button. The dropdowns stay the fast path on a small shelf; this is the walk-the-aisles view for a big one.

Where pieces get used

Connect / logon / goodbyeThemes page › Art: bind each slot to a piece.
Menu backdropMenus page: the Backdrop picker on the menu.
Per-level backdropsMenus page: Backdrops by level (first ACS match wins).
ANSI bulletinCommunity page: the art picker on the bulletin form.
ART menu itemThe item's argument names the piece.
Chapter 13

#The community desk

One console page, six tabs, alphabetical on the rail; the page opens on Auto-message.

  • Message boards (1.6.0): every category and board, listed the way a caller sees them, with live message counts. Open a board and every message is there, newest first, 25 to a page, with a one-click flip to oldest-first (the same date-driven order callers see, so a fixed timestamp re-files a message here too). You can edit the subject, the body, and the date and time stamp (entered in board time, stored UTC), and you can delete a message (soft, the same as caller-side deletes). Two things never change: who wrote it and where it sits in the reply tree. Those are facts of the record, shown read-only above the form. Private mail is a different matter entirely: mail areas are excluded from this tab at the query level. The console does not read anyone's letters.
  • Bulletins: title (60 characters), body (pipe colors render; word-wrap at the full 80 columns), or an ANSI art slot shown full-screen instead. ACS per bulletin; sort orders the list; a fresh save greets every caller once at next logon. Anything updated since a caller's last visit is shown to them automatically; the key for browsing them at will is whatever your menu designer says it is.
  • Oneliners / Rumors: callers write, you hold the eraser. One random rumor greets every logon; prune the duds.
  • Voting booth: question (100 characters) plus 2 to 10 options and an optional ACS. One ballot per caller; bar-graph results. No editing once ballots exist: close (results only) or delete (ballots too).
  • BBS list: the other-boards directory. Callers add (gated by the Settings ACS); you edit and delete. Addresses must be https://, telnet://, or host:port.
  • Auto-message: one board-wide wall message shown at logon; callers who pass its ACS rewrite it from the caller side.
Chapter 14

#Chat, break-in, paging and broadcast

  • The room: one public channel, every node. History pages with PgUp and PgDn or the arrows; a half-typed line survives paging; timestamps show the board clock with dates across midnight. Long lines word-wrap onto up to three display rows instead of clipping at the right edge, so every typed character shows.
  • Page SysOp: the caller pages with a reason; the console chat panel arrives pre-aimed at their node.
  • Break in: from the dashboard, next to any caller. Opens the private line: the caller gets a bell and a banner naming you, and the private conversation interrupts whatever screen they are on (except mid-editor, where it politely waits so their draft survives, and lands the moment they finish). Everything on the private line is invisible to the room. ESC or Q returns the caller to what they were doing.
  • The split screen (1.6.0): Settings offers a second style for the caller's side of a break-in or an answered page. In split, the caller keeps the top half of the screen for their own typing, your words fill the bottom half, and a dim rule with name tags divides the two: a proper old-style SysOp chat. Classic (one shared scroll) remains the default, the console side is identical either way, and the style is picked up fresh for each conversation.
  • The room keeps its history (1.6.1): housekeeping used to sweep every chat line older than seven days, so a board with a slow week woke up to an empty room. The public room now keeps its newest 1,000 lines however old they are, and only the overflow past that cap is swept. Transient wire traffic (page requests, private SysOp lines and their hang-up markers) still expires after a week, as it should.
  • Tidy the room (1.6.5): every public chat line on the console's live wire carries a delete link. One click and a confirm removes that line from the room for good, with an audit line in the admin 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.
  • Broadcast: a timed banner above every caller's screen for the minutes you choose. Never enters chat history.
Chapter 15

#Door games in the console

The registry

Every door is one folder, and door folders live in the doors/ directory of your ATDT installation, alongside the shipped games. If your board is at www.example.com/atdt, a door called Dice Run is atdt/doors/dicerun/. Scan reads that directory and registers what it finds.

atdt/ doors/ hilo/ shipped starmerchant/ shipped dicerun/ a door you uploaded README.md the door SDK walkthrough

Registering is all Scan does: no menu changes. To put a door in front of callers, use the Menus page like for anything else: add an item with the DOOR action, and every registered door is offered in the item's argument list automatically. Door entries are ordinary menu items: rename, re-key, reorder, hide or move them at will (the shipped DOORS menu's HILO and Star Merchant rows are just such items).

Per door here: enable or disable, display title, ACS, sort. A disabled door keeps any menu items but refuses to open; delete the item in Menus if you want it gone from the list too. A door whose folder went missing is flagged for re-upload or removal.

HILO

The number-guessing classic; no settings; its scoreboard feeds the Stats screen. Its source doubles as the SDK example.

Star Merchant

An original space-trading game in a persistent galaxy that generates itself the first time anyone opens the door. First-time players land on a two-page in-game primer; ? or H reopens it anywhere.

SectorsGalaxy size for the NEXT generation (takes effect on reset). Default 1000.
Turns per dayDaily action budget (default 250); the day-tick refills.
CombatMaster switch; off = purely economic galaxy.
Reset universeRegenerates everything and erases every player. Type RESET to confirm.
Top merchantsThe net-worth ladder.
Game logConquests, bounties, weekly ladder closes.

What the day-tick does: port stocks drift 15 percent toward full; colonized planets produce by class; banks earn 0.5 percent; turns refill; fresh derelicts scatter; pirate crews drift one warp and respawn toward one per 50 sectors (never into Charter Space, sectors 1 to 9); weekly, the ladder snapshots into the hall of fame.

Chapter 16

#The Door API

A door is one folder with a manifest and a PHP class. The board provides screen, input, storage and identity; the door returns frames. Nothing a door does can take the board down.

Chapter 17

#Cron and the daily tick

The cron endpoint runs housekeeping. With a real cron entry it fires every five minutes; without one, pseudo-cron performs the same work piggybacked on caller traffic (it kicks in when the last tick is older than 15 minutes, guarded by a lock so only one request does it). Either way:

  • Every tick: sweep dead sessions (nodes free up); prune events older than 90 days, and transient chat traffic older than 7 days. The public room keeps its newest 1,000 lines regardless of age (chapter 14).
  • At board midnight (your timezone): each enabled door's cron.php, then data/logs rotation.

The cPanel line, printed by the installer and the Settings page:

*/5 * * * * php /home/you/public_html/cron.php key=YOURKEY

The key guards the endpoint (cron.php?key=... over HTTP works too); wrong keys are refused and logged. The dashboard card shows minutes since the last tick.

Chapter 18

#Logs and events

Events logEverything notable, with a level. security covers login lockouts on both surfaces; cron records ticks and failures; perf appears if a response ever exceeds the 64 KB budget; door lines arrive tagged door:<slug>. Hang-ups land here too (1.6.0): a console Log off and an idle timeout each leave one line naming the node. Since 1.6.1, an applicant dropped for three prohibited handles in a row leaves a security line naming their address.
Admin logEvery console action with who did it, so a co-SysOp's work is auditable.
Call logOne row per call with duration and a summary ("Posted 2 msgs, played HILO").
Chapter 19

#Backups, upgrades and recovery

Backups

Everything that is yours lives in data/: configuration, the SQLite database, theme overlays, the art gallery, your letter fonts, door storage. Back up that one folder and you have the whole board (on MySQL, dump the database too). One thing sits outside it: a door you installed yourself is code in doors/, so keep its zip or fold that folder into the backup as well.

Upgrading in place

  • Upload the new release's files over the old ones. The zip contains no data/, so an overwrite upload cannot touch your data.
  • The first page hit migrates the database automatically if needed.
  • install.php coming back with the upload is harmless; it self-locks.

Skipping versions is fine. The migration is a single ladder keyed on the stored schema version: a board that missed a release (or five) climbs every rung it lacks, in order, on that same first hit. There is nothing to run by hand and no intermediate build to install; upgrading 1.0.0 to any future version is always the same overlay upload. The ladder runs under a lock so two simultaneous first-hits cannot collide, and the 1.1.0 rungs are safe to re-run if a crash interrupts them.

Recovering a lost SysOp password

With another level 255 account: reset it from the Users page. Without one: any database tool (or a one-visit PHP snippet you delete after) setting users.pass_hash to the output of PHP's password_hash() for your new password.

Troubleshooting

SymptomCause and fix
Board looks broken after upgradeStale cached client from a very old build; one hard refresh fixes it forever.
Installer says already installedBy design. Delete data/config.php only for a true wipe.
"Could not write" in the consoleFile permissions on data/.
Callers get BUSYAll nodes in use; raise Max nodes or wait for the sweep.
Menu will not go back to generatedA leftover per-level backdrop variant is outranking the picker. Chapter 10.3.
Cron card redThe cron entry stopped; re-check the line and key. Pseudo-cron keeps the board alive meanwhile.
Locked out of the consoleFive failed logins in 15 minutes; wait out the window.
Chapter 20

#Networking (coming in v2)

This chapter will cover joining a network, subscribing to areas, reading poll logs, and diagnosing dead links.

Not shipped yet. Message areas shared between ATDT boards are planned for version 2.0.0. The roadmap has what is known so far.
Appendix A

#Pipe color codes

|00 to |15 foreground, |16 to |23 background, || a literal pipe. Callers can read this same table on the board through a HELP menu item.

FOREGROUND |00 Black |08 Dark gray |01 Blue |09 Bright blue |02 Green |10 Bright green |03 Cyan |11 Bright cyan |04 Red |12 Bright red |05 Magenta |13 Bright magenta |06 Brown |14 Yellow |07 Gray |15 White BACKGROUND |16 Black |20 Red |17 Blue |21 Magenta |18 Green |22 Brown |19 Cyan |23 Gray
Appendix B

#MCI variables

These expand everywhere text is displayed, whoever typed them, SysOp or caller: theme strings, messages and mail (bodies and subjects), bulletins, oneliners, rumors, the auto-message, chat, BBS-list notes, the broadcast banner, and inside .ans art (the connect, logon and goodbye screens, menu backdrops, ART items, and art bulletins).

Each viewer sees their own values; the stored text keeps the codes. Unknown %-pairs pass through as typed. In art, a substituted value shifts the rest of its row, so leave drawing room around the code; on the connect screen, before login, %HN reads "caller".

%HNThe caller's handle
%LVLevel
%NDNode
%BNBoard name
%PHBoard number
%DTDate, board clock
%TMTime, board clock
%CTCalls today
%CACalls ever
%LCLast caller
%UTTotal users
%ANCurrent area name
%ADCurrent area description. New in 1.7.0.
%MCMessages in area
%VNATDT version
%BDThe viewer's connection speed: their own throttle if set, otherwise the board's Line speed. Reads FAST when the throttle is off. New in 1.6.0.
Appendix C

#Settings quick reference

SettingPage · one line
Board name / Base URL / TimezoneSettings · identity and the caller clock.
Board numberSettings · the ceremony's dial string; %PH.
Max nodesSettings · simultaneous caller cap (10).
New user policy / questionSettings · approve, auto, closed.
BBS list additionsSettings · ACS to add directory entries.
Banned addressesSettings · IPs (exact or prefix) refused before the ceremony.
iCE colorsSettings · bright backgrounds vs blink.
Connect ceremonySettings · the fake handshake.
Allow user colorSettings · caller pipe codes render.
Default themeSettings · what everyone sees unless set per caller.
Line speedSettings · board default baud; new callers start here; the CONNECT number.
Idle hang-upSettings · quiet minutes before the line lets go, any screen (30; 0 off).
SysOp chat styleSettings · classic scroll or split screen, as the caller sees it.
Prohibited wordsSettings · handles refused at the application desk; three in a row drops the line.
SysOp notificationsSettings · pages as browser push, opt-in per browser, HTTPS only.
Outgoing mailSettings · send-only email: resets, EMAILSYSOP, the email asks.
Cron keySettings · guards cron.php.
Theme (per caller)Users · "(board default)" or a specific wardrobe.
Email (per caller)Users · where that caller's password resets go.
The logon tourSettings · the order of the cards after the password, or none at all. New in 1.7.3.
DOS doorsSettings · master switch for original DOS door games; off by default. New in 1.7.0.
Board offlineSettings · nobody connects, not even you, until it flips back. New in 1.7.0.
Last call (per caller)Users · set or clear a caller's last call date. New in 1.7.0.
ListedAreas · checked (default), the area appears in the general area-change list. Unchecked, it leaves that list and nothing else. Discovery, not security (9.3). New in 1.6.5.
Area scopeMenus · blank (default), this menu shares the board's current message area. A name: this menu keeps its own, shared with menus naming the same scope (10.4). New in 1.6.5.
Default areaMenus · the board a caller starts in the first time they read or post in this section. Blank: their first read shows the picker. Only meaningful with an Area scope. New in 1.6.5.
Area / Limit to categoryMenus, item form · the item's second argument, shown only for read, post, newscan, setarea and setareaback (an area) and areachange (a category). See 10.2. New in 1.6.5.
Door enable / ACS / sortDoors · which games, to whom, in what order.
Appendix D

#What lives where

atdt/ index.php the caller terminal page api.php the terminal talks to this install.php the installer (self-locking) cron.php the housekeeping endpoint admin/ the SysOp console assets/ terminal client, editor, fonts lib/ the board engine themes/default/ the shipped fallback theme (never editable) doors/ shipped door games + any you install + the SDK README data/ YOURS: config, database, themes, art, fonts, doors, logs art/ the art gallery: every .ans piece, board-wide themes/ your theme copies (strings.ini + art.json each) fonts/ letter fonts you drew (1.5.5)

Back up data/. Everything else is replaceable from the release zip, except doors you installed yourself.

↑ Back to the top