One address for every board of the network: pick one from the menu and the gate puts you through; when that board hangs up, you are back at the menu. And Global Discovery: the world's other telnet BBSes in one searchable list, each with the result of our last call, dialled the same way.
Live at
teletypegames.org:2399, and in the browser on bbsweb (the last card)
TTG Gate BBS is a dialing menu and nothing more, the telnet counterpart of the list on bbsweb. It runs no board of its own: the chosen board's own port takes the call through a telnet gateway of rubbs (BBS::Gateway) (the Teletype BBS has no gateway doors of its own since 2026-11-01: the gate is the one way through). Every board keeps its code, its port and its deploy; the gate only carries the bytes.
Like every board of the BBS Network it has two faces on one port, and a call starts with the same terminal question:
Q or Esc hangs up.TTG GATE logo with the node and the clock; two tabs, Own Servers and Global Discovery, the active one a band in its colour, with the boards online on the right; under them the active tab's sub-menu (/Find, Browse, New, Random, Died, Graves, Srcs, their keys in yellow); the content across all 40 columns; and a hint bar of the screen's keys. Own Servers lists our boards that have a C64 face: a block of the board's colour, its name and port, and under the list the lit board's description, address and tags. O and D switch the tabs from anywhere; CRSR up and down move in a list, and on Global Discovery CRSR up from the top of the list goes to the sub-menu (left and right move its bar, RETURN opens, CRSR down goes back); a yellow key opens its place from anywhere; RETURN opens or dials, ← or RUN/STOP goes back, Q hangs up.
The board asks its own terminal question first. The gate reports the caller's window size to it, so a modern terminal is its default; a C64 reports none, so the board takes it for a C64. RETURN takes the guess.
Leave the board the way you always do (log off, Alt-X, Q on a C64): the gate says that it hung up, and a key brings the menu back.
Besides our own boards, the gate keeps a catalog of the world's other telnet BBSes, from public lists, and calls every one of them once a day to see whether it answers. Nothing in it is written by hand: every field comes from a source list, from our own call, from DNS or from a fixed rule table, and no language model is involved. Only telnet; no SSH, rlogin or web addresses.
On the modern face, Global Discovery has:
| Entry | |
|---|---|
| Every board | all but the dead ones, the answering ones first, then by name |
| Search | / anywhere; see below |
| Browse | by Terminal (ANSI, PETSCII, ASCII, ATASCII), Software, Country and Network, each with its count |
| New this week | the boards a list named first in the last 7 days |
| Random board | one that answered our last call |
| Recently died | the boards that turned dead in the last 30 days |
| Graveyard | every dead board: none is ever deleted, its history stays |
| Sources | the lists, their credits, DB-IP, and how to opt out |
A list shows the state of each board: ● online, ◐ flaky, ✗ down (with how long: "down for 3 days"), † dead, ? not called yet. F filters by state, the arrows and PgUp/PgDn page. The board's own page has its address, state and last answer, why our server did not reach it (a name that does not resolve is not the same as a firewall), a strip of the last 30 days (█ answered that day, · did not), every field with the list it came from, the FTN address, the tags, and B for the first screen of its banner.
Search reads its words as tags where it can: petscii hu online is the encoding, the country and the state together, synchronet, fidonet or sbl find the software, the network or the list. The other words search the names, sysops, places, software and host names, each word the start of a word there. The dead boards stay out unless the search says all. FTN mailers (mail programs answering a nodelist's telnet address, not BBSes) are never listed unless searched for as sw:ftn-mailer.
On the Commodore 64, D (the Global Discovery tab) opens Global Discovery in the same frame: ten boards a page under a row of filter chips (PETSCII, and the state F chose: alive, online, flaky, down, not called yet), each with its state mark (a half block: light green online, yellow flaky, red down, grey dead), name, country and software, and under the list the lit board's whole address, state, latency, software and terminals. Only PETSCII boards are on it, the dead ones apart but in Died, Graves or a search with all, since the gate carries the bytes as they are and an ANSI board is noise on a C64. A board is a PETSCII board when one of our calls got PETSCII from it, not because a list says so (see the C64-style call below). Find (/) is typed on the hint row; Browse (B) has Software, Country and Network; S opens the Sources. A board's page shows the 30-day strip, the fields (a long value wraps) with the list each came from, the tags as chips, and the buttons: RETURN dials, B shows its PETSCII banner. Sources draws each list with a bar of its records, whether its last import went well and how long ago, its format and terms, and PETSCII measured against claimed.



RETURN on a board's page dials it, through the same gateway as our own boards; when it hangs up, a key brings back its page, and Q (on a C64 ←) the list where you were.
The prober runs on our server (teletypegames.org, vps.teletype.hu) and calls only the addresses the source lists publish: nothing is scanned.
ANSI, a window of 80×25; every other option is declined.ok (a banner came), silent, closed, refused, timeout or dns_fail.The C64-style call. Because the prober says it is an ANSI terminal, a board that adapts to its caller shows it ANSI, while a real Commodore 64 (a terminal program behind a WiFi modem, which knows no telnet) would get PETSCII. So a board a list calls a Commodore or PETSCII board (every board of the CBBS Outpost, a SyncTERM entry in C64 mode, a PETSCII comment in the SBL, a Telnet BBS Guide entry naming PETSCII or running a Commodore BBS program), or whose banner was PETSCII, is called a second time, 30 seconds after its daily call answered, the way a C64 calls: the same connection, one Enter (CR, 0x0D) after 4 seconds of silence, but every telnet option declined, no terminal type, no window size, and a longer window, since a real C64 behind tcpser may answer late: up to 20 seconds for the first byte, reading until 25 seconds or 4 KB. It belongs to the same daily round and never runs beside another call to the host, so these boards get at most two calls a day; after a failed call there is no C64-style one, and a silent one is tried again the next day. It does not count towards the board's state.
A board gets the petscii tag only when one of the two calls actually got PETSCII bytes. What a list says is kept as claims:petscii, a tag you can search for but that is not shown: a Commodore-listed board whose C64-style call gets ANSI or plain text is no PETSCII board. A board that shows ANSI to our terminal and PETSCII to a C64 gets both tags and can be dialled from both faces; both banners are kept, the modern face plays the ANSI one, the C64 face the PETSCII one.
An answering board is called once a day (± 2 hours), a failing one again after 1, 6 and then 24 hours, a dead one (no answer for 30 days) weekly; a board that no list names any more and has been dead for a year is no longer called. At most 8 calls run at once, never two to the same host or IP address. The software and the encoding come from the banner by a fixed table of patterns, the country from the IP address.
A sysop can ask for either of two things, for a host name or an IP address (every port of it):
Send the host name or address and the level to the Teletype Games team (contact: Discord or e-mail). The entry goes into config/discovery-optout.yml, and the prober honours it within the hour of the push.
| Source | What we read |
|---|---|
| FidoNet nodelist (Z2DAILY, via NodelistDB) | the nodes with a telnet address: name, place, sysop, FTN address |
| fsxNet nodelist | the same, for fsxNet |
| Micronet nodelist | the same, for Micronet |
| Synchronet BBS List, exported from Vertrauen | name, sysop, place, software, addresses, networks, year of start |
| SyncTERM BBS list | name and telnet address |
| CBBS Outpost (commodorebbs.com), the list of Commodore boards | name, telnet address, place, software, hardware, website |
| Telnet BBS Guide (telnetbbsguide.com), used with permission | the monthly list: name, telnet address, place, software, website |
We read the listed facts of each board and never republish the files. From the CBBS Outpost (commodorebbs.com) we take the facts only, once a day in one request, with its credit on every board page it names and on the Sources screen: never the sysop's name, e-mail or user name, screenshots, comments or the site's own online mark; its listing of a Commodore board is a claim that our C64-style call checks. Its sysops can ask us to take an entry down, as in Opting out. For a board it lists, its software and place come first. The Telnet BBS Guide (telnetbbsguide.com) is used with its permission: we read its official monthly list, the one it publishes for distribution, never its e-mail addresses or descriptions (a description only tells whether it names PETSCII), and only the telnet entries. It is the largest list, but edited by hand once a month, so for a board the nodelists and the SBL name, their fields come first. The countries come from DB-IP's IP to Country Lite database, under CC BY 4.0: IP Geolocation by DB-IP; we keep our own copy, downloaded monthly.
The boards come from config/boards.yml, in the order of the menu, with the names, descriptions, tags and accent colours of their bbsweb cards:
| Field | |
|---|---|
id |
a short name, unique |
name |
shown in the menu |
summary |
the description on the modern face |
tags |
the line under the name on the C64 face |
port |
the board's port |
accent |
the board's colour, #rrggbb (the nearest of xterm's 256, or of the C64's) |
petscii |
true when the board has a C64 face |
enabled |
false keeps it out of the menu |
A new board of the network gets an entry here as part of the new board checklist; a push to master deploys it.
| Variable | Default | |
|---|---|---|
TTG_GATE_BBS_GATEWAY_HOST |
host.docker.internal |
where the boards are dialled |
TTG_GATE_BBS_PUBLIC_HOST |
teletypegames.org |
the address shown with every board |
TTG_GATE_BBS_BOARDS |
config/boards.yml |
the boards list |
TTG_GATE_BBS_DIAL_WINDOW |
600 |
Global Discovery: the window of the per-caller dial limit, seconds |
TTG_GATE_BBS_DIAL_PER_CALLER |
10 |
the dials one caller may make in the window |
TTG_GATE_BBS_DIAL_PER_HOST |
3 |
the lines from the gate to one host at once |
The layers of the house standard: BoardModel, BoardRepository (the YAML file), DirectoryService and the composition root TTGGateBBS; the faces are UI::Modern (the chooser, the selector and the Discovery screens) and UI::Petscii (the frame with its tabs and sub-menu, and the views, drawn as changed cells only). Global Discovery lives in lib/domain/discovery/: the catalog is a SQLite file (data/discovery.sqlite3, WAL, FTS5) that the daily import and the prober (its own container, ttg-gate-bbs-prober) write, and the gate reads, but for the record of its dials (BrowseService, DialService). The gateway's report of a call comes from rubbs 0.31 (BBS::Gateway::Report). The numbers go to data/discovery-metrics.prom (ttg_gate_bbs_discovery_*, among them the dial limits, how near the callers and hosts are to them, the refused dials by reason, and the time and traffic of the dials) for Grafana. A push to master deploys it from Woodpecker (RuboCop, compose check, ci-deploy ttg-gate-bbs); the container is ttg-gate-bbs, in /srv/stacks/ttg-gate-bbs, and it reaches the boards on their host ports (host.docker.internal). Those internal connections are exempt from the per-IP limits of vps-bbs-firewall, so every caller of the gate counts once.