ATDT Demo board online

Documentation

The Sysop's Manual

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

ATDT BBS 1.0.0 · last revised for version 1.0.0

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.

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 caller text.
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 for you on its first screen and explains anything that is missing.

The install wizard

  • Step 1. Upload the contents of the atdt/ folder to your web space. The web root and a subdirectory (for example /bbs/) both work.
  • Step 2. Visit https://your-site.example/install.php. The environment check runs.
  • Step 3. 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 button.
  • Step 4. 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 base URL (auto-detected; correct it if your board lives behind a different public address).
  • Step 5. Done. The installer prints your cron line 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 again while data/config.php exists.

The cron job

The board does housekeeping on a schedule: the daily tick at board midnight, session sweeps, and each door game's own daily work. The installer prints a line like this for cPanel's Cron Jobs page:

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

The key is a long random string that guards the endpoint. If you cannot add cron jobs, skip it: pseudo-cron runs the same housekeeping piggybacked on caller traffic. A real cron entry is only better because it fires even when the board is quiet.

Reinstalling

To wipe the board 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 are logged), and every session rides a CSRF-protected cookie.

A sensible first hour:

  • Open the board itself in another tab and look around as a caller. The seeded board has two message areas on a "Main Boards" shelf, a welcome bulletin, and two doors.
  • Settings: confirm the board name, timezone and base URL. Decide your new-user policy (chapter 6).
  • Community: rewrite the welcome bulletin in your own voice.
  • Areas: rename the starter areas or build your own layout with categories (chapter 9).
  • Themes and the ANSI editor: draw or import a logon screen (chapters 11 and 12).
  • 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×25 CP437 screen rendered with a real IBM VGA font. Callers type; the board answers. Menus respond to single hotkeys, prompts take a line of input, and the full-screen editor opens for message writing.

The matrix and new users

Before login a caller can press L to log in, A to apply for an account, or G to log off. Applications ask for a handle, password, location, and your custom question. What happens next depends on your new-user policy: with approve the account waits for you (the dashboard shows pending callers), with auto it activates immediately, with closed no applications are taken.

The post-login sequence

After a successful login the caller rides the classic ceremony: connect banner, logon art, board news, a fresh bulletin if one changed since their last call, the auto-message wall, a random rumor, mail check, and last callers, then lands at the MAIN menu. Each step advances on any key.

The default menu map

KeyGoes to
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 is 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 yours to change in the menu designer.

Caller-side settings

The "Your settings" screen gives each caller a terminal bell toggle, a nostalgic connection-speed throttle (300, 1200, 2400, 9600 baud, or off; keypresses drain the buffer instantly), and a password change.

Chapter 05

#The dashboard

The console home page is the pulse of the board. Everything urgent surfaces here.

The stat cards

  • Calls today and total calls for the board.
  • Messages posted today.
  • Pending callers: applications waiting when your policy is approve. Approve or reject inline.
  • Cron health: minutes since the last tick. It stays green under pseudo-cron too; -- means cron has never run.

Who is online

Every live node with handle, node number, what they are doing, and idle time. Two buttons per caller:

  • Join chat: drops you into the public room the callers see.
  • Break in: opens a private line to that caller. See chapter 14.

The chat panel

The console chat panel mirrors the room without you being a node. The target selector aims your words: everyone in the public room, or a private line to one node. A loud banner above the box always shows where the next line goes, and when a caller pages you the form arrives pre-aimed at them.

The broadcast banner

Type a message, pick the minutes, and every connected caller sees it as a banner above their screen no matter what they are doing. Good for "board restarts in 10 minutes." It is separate from chat: a broadcast never lands in the room history.

Chapter 06

#Settings, every field

Identity

Board nameShows in the terminal title, banners, and %BN wherever theme strings use it.
Base URLThe public address of the board. Used in generated links and the cron advice. Fix it if you move the board.
Board timezoneThe clock callers see everywhere: message stamps, last callers, chat. Storage stays UTC; this is display and the daily-tick boundary.

Access

Max nodesHow many callers may be connected at once (default 10). The next caller past the cap gets a busy screen, just like a full modem bank.
New user policyapprove: applications wait for you. auto: accounts activate instantly. closed: no applications taken.
New user questionYour custom question on the application form. Answers land in the caller's note field for review.
BBS list additionsACS for who may add entries to the BBS directory (blank = everyone, v = validated callers). Viewing is always open.

Display

iCE colorsLets art use bright backgrounds instead of blinking text, the classic iCE trick. Turn it on if your art uses bright backgrounds; leave it off for authentic blink.
Connect ceremonyThe fake modem handshake on connect: dial tones, CONNECT banner. Pure theater; off means straight to the matrix.
Allow user colorWhen on, callers may color their own text with pipe codes in messages, mail, chat, oneliners, rumors and the auto-message. When off, codes show as typed.

The cron key

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

Chapter 07

#Users and access

The list

Search by handle, filter by status, sort by any column. The list caps at 200 rows and tells you to narrow the search past that. Pending applications float to the top with one-click approve.

The edit drawer, field by field

LevelSecurity level 0 to 255. New callers start at 10. 255 is sysop: passes every ACS and may enter the console.
FlagsTwenty-six checkboxes, A to Z. Flags mean whatever you decide; ACS strings test them with fA, fB and so on. Hand them out like club cards.
Statusactive (may log in), pending (awaiting approval), locked (refused at the matrix), deleted (soft; the row stays for history).
LocationFree text shown in the user list and last callers.
NotePrivate sysop note. Application answers land here.
ThemeWhich theme this caller sees (chapter 11).
New passwordType once to reset a forgotten password. Blank leaves it alone.

The level ladder

10A fresh caller.
20 and upYours to define; gate areas or menus with s20, s50 and so on.
100A handy co-sysop line: gate staff areas with s100.
255Sysop. Console access. Passes every ACS automatically.
Deleting is always soft. The handle stays reserved and history stays intact. Lockouts from failed logins clear themselves after 15 minutes; the events log records each one.
Chapter 08

#Access strings (ACS)

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

TokenPasses when
s50Caller level is 50 or higher.
fACaller has flag A.
vAccount is validated: active, not a pending application.
!fZNOT: caller does not have flag Z.
s50fBSide by side means AND: level 50 or higher and flag B.
s50|fBThe pipe means OR: level 50 or higher or flag B.
(s50|fB)!fZParentheses group: (level 50+ or flag B) and not flag Z.

Recipes

vMembers only. Keeps pending accounts out.
s100Co-sysops and up.
fPWhoever you handed the P flag.
s255You alone. Secret menus, staff boards.
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 message reader labels the area as "Category / Area."

Categories

  • Add: name up to 30 characters. New categories land at the end of the order.
  • Rename inline, reorder with the arrows. The caller list follows this order exactly.
  • Delete: the category goes away, the areas inside it stay, loose. Nothing else is touched.
  • Areas without a category gather under "Other Boards" at the end of the list. A board with no categories at all shows the plain flat list.

Areas, field by field

TagShort unique key, 2 to 12 characters (A to Z, digits, underscore). Shows in the caller list and in message IDs.
NameThe display name, up to 40 characters.
DescriptionOne line under the name in the caller list, up to 100 characters.
CategoryThe shelf it lists under, or none.
Read ACSWho sees the area at all. Blank = everyone.
Write ACSWho may post there. Blank = everyone. For a read-only announcements area, set write ACS to s255.
  • The arrows reorder an area within its own category, which is the order callers see.
  • Delete refuses while the area still holds messages; empty it first.
  • The private mail spool is plumbing, not an area; the console will not let you edit or delete it.
Chapter 11

#Themes

A theme is the board's wardrobe: every caller-visible string plus the art files. The shipped default theme is read-only; the console duplicates it into data/themes/<name> and you edit the copy. You can never break the board permanently: anything missing in your copy falls back to the shipped look.

The Themes page

  • Duplicate: copy any theme into an editable one under data/themes/.
  • Strings: every caller-facing string, grouped, with a live pipe-code preview as you type. Save writes your strings.ini overlay.
  • Art: the theme's .ans slots. Upload rules: .ans files only, 256 KB cap, always served through the board's CP437 loader.
  • Delete: blocked while any caller still wears the theme. Reassign them on the Users page first. Deleting a copy of a shipped theme lets the shipped version show through again.

Assigning themes

Themes are per caller: the Theme field in each user's edit drawer. New accounts get default.

Well-known art slots

connectThe connect ceremony screen.
logonThe welcome screen in the post-login sequence.
logoffThe goodbye screen.
(any name)Menu backdrops, ART menu items and ANSI bulletins can use any slot you invent.
Chapter 12

#The ANSI editor

A full drawing program at Console › Editor: an 80×25 CP437 canvas rendered with the same engine callers see, so what you draw is exactly what ships. It saves straight into a theme's art slots.

Tools

Pencil (P)Stamp the current glyph in the current colors.
Half-block (B)Paint with half-height blocks: an 80×50 pixel feel. Right-drag erases.
Text (T)Click and type. Arrow keys move the caret.
Line (L)Drag to draw a straight run of the current glyph.
Rectangle (R)Drag to draw a border box.
Flood fill (F)Fill a connected region with glyph and colors.
Select (S)Drag a box, then Copy, Move or Blank it. Click to place.

Color, glyphs and the keyboard

  • Palette: 16 foreground colors, 8 backgrounds. With iCE colors on, backgrounds get all 16.
  • The glyph row holds the full CP437 set: box drawing, shades, blocks, symbols. Click to arm the pencil with any of them.
  • Undo is Ctrl+Z, redo is Ctrl+Y. Zoom and a grid overlay are on the toolbar.
  • The canvas autosaves to your browser while you work, so an accidental tab close loses nothing.

Files: save, import, export

  • Save to slot: writes the drawing into the chosen theme's art slot as a real .ans file with a SAUCE record. Anything wired to that slot updates instantly.
  • Import: upload any .ans (256 KB cap), including classic scene art with iCE backgrounds; it lands on the canvas for editing.
  • Round trips are pixel-identical: import, edit, save, and the render matches byte for byte where you did not touch it.

Wiring art into the board

  • Logon and connect screens: save to those slots in the caller's theme.
  • Menu backdrops: attach the slot on the menu designer page, with an ACS per variant.
  • ANSI bulletins: pick the slot on the bulletin form; callers get the art full-screen.
  • ART menu items: point the item's argument at the slot.
Chapter 13

#The community desk

One page, five tabs: everything callers write that you curate.

Bulletins

  • Title up to 60 characters. Body text renders pipe colors and word-wraps at the full 80 columns, so classic-width text pastes cleanly.
  • Or attach an ANSI art slot instead: callers get the art full-screen.
  • ACS gates who sees each bulletin; sort orders the list.
  • A freshly saved bulletin greets every caller once at their next logon.

Oneliners and rumors

Callers write them; you hold the eraser. Oneliners are the graffiti wall, one per caller per board day. One random rumor greets every caller at logon, so prune the duds.

The voting booth

  • A question takes up to 100 characters and 2 to 10 options, one per line, with an optional ACS.
  • One ballot per caller per question; results draw as bar graphs.
  • Questions cannot be edited once ballots exist. Close them (callers see results only) or delete them (ballots and options go too).

The BBS list

The other-boards directory. Callers add entries, gated by the Settings-page ACS; you edit or delete anything. Addresses must be https://, telnet://, or host:port.

The auto-message

One board-wide wall message, shown in the post-login sequence. Callers who pass its ACS rewrite it from the caller side; the previous message is simply replaced.

Chapter 14

#Chat, paging and the broadcast banner

The room

One public chat room, every node together. Callers page through history with PgUp and PgDn (or the arrow keys), and a half-typed line survives paging. Timestamps show the board clock, with dates when history crosses midnight.

Page sysop and the private line

  • A caller pages you with a reason; the console chat panel rings and arrives pre-aimed at their node.
  • Break in, on the dashboard next to any caller, opens the private line yourself. The caller gets a banner naming you; everything either of you types rides caller-to-sysop only, invisible to the room.
  • Callers answer from wherever they are; they do not need to be in the chat room. ESC ends their side.

Broadcast

The dashboard broadcast form puts a timed banner above every connected caller's screen for the minutes you choose. It never lands in chat history. Use it for maintenance warnings and event calls.

Chapter 15

#Door games in the console

The registry

  • Scan finds new doors in doors/ (shipped) and data/doors/ (yours) and registers them.
  • Per door: enable or disable, display title, ACS, and sort order. Disabled doors vanish from caller menus instantly.
  • A door whose folder went missing is marked so you can re-upload or remove it.

HILO

The shipped number-guessing classic. No settings; its scoreboard feeds the Stats screen. Its source is deliberately small: it doubles as the Door API example.

Star Merchant

The flagship: an original space-trading game in a persistent galaxy. The universe generates itself the first time anyone opens the door.

The console panel

SectorsGalaxy size for the next generation; takes effect on reset. Default 1000.
Turns per dayEach merchant's daily action budget. Default 250; the day-tick refills it.
CombatMaster switch for fighting. Off makes the galaxy purely economic.
Reset universeRegenerates every sector, port and warp, and erases every player. Type RESET to confirm.
Top merchantsThe current net-worth ladder.
Game logRecent in-game events: conquests, bounties, weekly ladder closes.

What the day-tick does to the game

  • Port stocks drift 15 percent back toward full, so gluts clear and famines refill.
  • Colonized planets produce by class, per thousand colonists.
  • Bank balances earn half a percent; every merchant's turns refill.
  • Fresh derelicts scatter for scavengers; pirate crews drift one warp and replenish to roughly one per 50 sectors.
  • Weekly, the net-worth 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 gives it a screen, input, storage and player identity; the door gives back frames. Nothing a door does can take the board down: every crash is caught, logged, and turned into a polite apology while the caller returns to the menu.

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. Either way the work is the same and runs at most once per due moment:

  • Sweep dead sessions so nodes free up.
  • At board midnight, in your timezone: the daily tick. Board-day counters roll; each enabled door's cron.php runs in its own try/catch.
  • Log every run; the dashboard cron card shows minutes since the last tick.

The endpoint requires the key: cron.php key=YOURKEY from the command line, or cron.php?key=YOURKEY over HTTP. A wrong key is refused and logged.

Chapter 18

#Logs and events

The events logEverything notable, with a level. security entries cover login lockouts on both the matrix and the console. cron entries record ticks. perf entries appear if a response ever exceeds the 64 KB budget. Door log lines arrive tagged with the door slug.
The admin logEvery console action with who did it (area edits, user changes, theme saves, door scans), so a co-sysop's work is auditable.
The call logOne row per call with duration and a summary of what the caller did: "Posted 2 msgs, played HILO."
Chapter 19

#Backups, upgrades and recovery

Backups

Everything that is yours lives in data/: the configuration, the SQLite database, theme overlays and door storage. Back up that one folder and you have the whole board. On MySQL, dump the database too. Restoring is copying it back.

Upgrading in place

  • Upload the new release's files over the old ones. The zip contains no data/ folder, so an overwrite upload cannot touch your data.
  • The first page hit after the overlay migrates the database automatically if the new version needs it.
  • install.php coming back with the upload is harmless: it sees the existing board and locks itself.

Recovering a lost sysop password

  • If another level 255 account exists, reset the password from its console, on the Users page.
  • If not: upload a one-line PHP file, visit it once, then delete it.
<?php $c = require 'data/config.php'; // adapt the DSN from it, then: // UPDATE users SET pass_hash = password_hash('newpass', PASSWORD_DEFAULT) // WHERE handle = 'YourHandle';

Any database tool works too; the only rule is that the stored value must come from PHP's password_hash().

Troubleshooting

SymptomLikely cause and fix
Board looks broken after an upgradeA stale cached client from a very old build. One hard refresh (Ctrl+Shift+R) fixes it forever; all assets are version-stamped now.
Installer says already installedBy design. Delete data/config.php only if you truly want a wipe.
"Could not write" in the consoleFile permissions on data/. The web user must own it or be able to write it.
Caller stuck at BUSYAll nodes in use. Raise Max nodes on the Settings page, or wait for the session sweep.
Cron card redThe cron entry stopped firing. Re-check the crontab line and the key; pseudo-cron keeps the board alive meanwhile.
Locked out of the consoleFive failed logins in 15 minutes. Wait out the window; the events log shows the attempts.
Appendix A

#Pipe color codes

Pipe codes color text anywhere the board renders them: theme strings, bulletins, menus, and, when Allow user color is on, caller text. || prints a literal pipe. Codes 00 to 15 set the foreground, 16 to 23 the background.

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

Theme strings substitute these live values wherever %XX appears. Caller-typed text never expands them.

%HNThe caller's handle
%LVThe caller's level
%NDTheir node number
%BNThe board name
%DTThe date, board clock
%TMThe time, board clock
%CTCalls today
%CACalls ever
%LCThe last caller's handle
%UTTotal user accounts
%ANThe current message area name
%MCMessages in the current area
Appendix C

#Settings quick reference

SettingPage · one line
Board nameSettings · the name everywhere.
Base URLSettings · public address of the board.
Board timezoneSettings · caller-visible clock and the daily-tick boundary.
Max nodesSettings · simultaneous caller cap (default 10).
New user policySettings · approve, auto, or closed.
New user questionSettings · your application question.
BBS list additionsSettings · ACS to add directory entries.
iCE colorsSettings · bright backgrounds instead of blink.
Connect ceremonySettings · the fake modem handshake.
Allow user colorSettings · callers may use pipe codes.
Cron keySettings · guards cron.php; mint anew anytime.
Theme (per caller)Users · which wardrobe each caller sees.
Door enable / ACS / sortDoors · which games show, 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 theme (read-only) doors/ shipped door games + the SDK README data/ YOURS: config, database, themes, doors, logs config.php connection + secrets (never world-readable) atdt_????????.sqlite the board, randomized filename themes/ your editable theme copies doors/ doors you installed doorstore/ per-door file storage

Back up data/. Everything else is replaceable from the release zip.

↑ Back to the top