---
title: 'Teletype BBS'
url: 'https://wiki.teletypegames.org/services/teletype-bbs'
markdown: 'https://wiki.teletypegames.org/services/teletype-bbs.md'
lang: en
date: '2026-06-03'
description: 'Teletype BBS is the clubhouse of the Teletype Games BBS Network: a Telnet, Synchronet-style bulletin board with message boards, mail, chat and the doors that live only here. Live at teletypegames.org:2323 Overview A Ruby app on the rubbs gem, our in-house BBS framework — it provides the ANSI inte…'
taxonomy:
  tag:
    - howto
---

# Teletype BBS

> Teletype BBS is the clubhouse of the Teletype Games BBS Network: a Telnet, Synchronet-style bulletin board with message boards, mail, chat and the doors that live only here.
> 
> **Live at `teletypegames.org:2323`**

# Overview

A Ruby app on the [**rubbs**](https://git.teletypegames.org/engines/rubbs) gem, our in-house BBS framework — it provides the ANSI interface, menubar, stacked modal windows, Telnet server and xterm mouse support. The `teletype-bbs` repo holds only the Teletype-specific parts: the domain (services wired to their stores), the windows and menus of the modern face, the PETSCII face, the doors and the characters.

The board was the first of the network, so once everything of Teletype Games was in it. Since 2026-11-01 it keeps the **community** and the **doors that live only here**; what another board carries is not repeated, the board only tells where it is:

| Looking for | Where it is |
|---|---|
| our games and files (C64, Plus/4; ZMODEM, XMODEM) | [WarpEngine BBS](https://wiki.teletypegames.org/services/warp-engine-bbs), `teletypegames.org:2329` |
| the wiki: guides, how-tos, the DOS corner | [TTG Wiki BBS](https://wiki.teletypegames.org/services/wiki-bbs), `teletypegames.org:2325` |
| the blog | [TTG Blog BBS](https://wiki.teletypegames.org/services/ttg-blog-bbs), `teletypegames.org:2328` |
| ANSI and PETSCII art | [Pixelia BBS](https://wiki.teletypegames.org/services/pixelia-bbs), `teletypegames.org:2332` |
| the debrief terminal of *Definitely not an Impostor* | [Impostor BBS](https://wiki.teletypegames.org/services/impostor-bbs), `teletypegames.org:2324` |
| Wikipedia, news feeds, books, the C64 game compendium | [Alexandria BBS](https://wiki.teletypegames.org/services/alexandria-bbs) 2326, [Feedia BBS](https://wiki.teletypegames.org/services/feedia-bbs) 2327, [Scriptorium BBS](https://wiki.teletypegames.org/services/scriptorium-bbs) 2330, [Commodex BBS](https://wiki.teletypegames.org/services/commodex-bbs) 2331 |
| all of them from one port | [TTG Gate BBS](https://wiki.teletypegames.org/services/ttg-gate-bbs), `teletypegames.org:2399` |
| the FTP tree for old machines | `ftp.teletypegames.org`, and on plain HTTP at `archive.teletypegames.org` |

**Board > BBS Network** (and Help > *Where are the games, files, wiki?*, `N` on the C64) shows them as the town map on the clubhouse wall, and the TTG Master answers the same.

Since 2026-11-01 the board looks like what it is, a **clubhouse** (see *The clubhouse* below). A call starts the old way: the modem dials and connects (`CONNECT 38400/ARQ/V42BIS`), then the caller stands at the **entrance**: the door under its lamp, the bell, the coats of the callers inside on the rack, and the open guestbook with the last three guests and the number of this entry (the caller number). The name (blank = Anonymous) and a registered name's password are written into the guestbook; any other name is a guest. Then the **logon sequence**: *Welcome back*, the caller number, your calls (first, last, time on line), and the scans of the old boards — new letters, new messages on each board since you last read it, polls waiting for your vote — and the quote of the day, a member's motto. ENTER opens the full-screen shell on the **dashboard**, the clubhouse from the street: a lit window for every caller inside, smoke from the chimney while the live chat talks, the mailbox flag for your letters, then who is inside, the notice board and the graffiti wall, refreshed every few seconds; **Board > Dashboard** closes every window and brings it back. While a menu is open, the bottom line tells what the highlighted item does. Every window wears the colour and the icon of its menu: Board pale teal ☼, Messages green ✉, People pink ☺, Doors salmon ♫, You grey ♥, Help yellow ¿. **Board > Log off** (Alt-X) puts the lamps of the clubhouse out one by one, with the coat ticket (the caller number and the time on line), a tagline, `+++`, `ATH0`, `NO CARRIER`.

The statusbar shows the node, the clock and the time on line.

# Features

**The board**

- **Dashboard** (Board) — the clubhouse from the street, live: the windows, the smoke, the mailbox; **Inside now** (the nodes and the guestbook of the last callers), **On the notice board** (the coming events with a bar filling as the day nears, the new notes on the cork board, your mail) and the graffiti wall of the oneliners. The card of the room whose window is open sits over the top of the house.
- **Bulletins** (Board > Bulletins…, Help > New to BBSes?) — numbered: the logon bulletin (the board in numbers, the newest posts, what is coming up, the last callers, the wall), *About Teletype Games*, *Coming up*, the board rules, *New to BBSes?* and the BBS network.
- **Dev Log** (Board) — the public activity of every organisation on [git.teletypegames.org](https://git.teletypegames.org): pushes with their commit messages, tags, releases and new repositories, newest first. Read anonymously from the Gitea API, so private repositories never show up.
- **BBS Network** (Board) — the town map: every board of the network a building in its bbsweb colour around the clubhouse; the arrows walk from building to building, under the map what the chosen one carries and how to walk over. The list with bbsweb and the FTP tree on plain HTTP is a bulletin. The board has no gateway doors: a caller goes to another board by calling it, or through TTG Gate BBS.
- **TTG Master** (`F1`, the button in the desktop's corner, Help) — the sysop who answers callers' questions about the board: where things are, what is coming up, and which board of the network carries what this one does not. The code looks up the facts (a knowledge file of the menus and of the other boards, the latest releases, the events, the games), the model only words them, and the code checks that the wording kept the facts and invented no menu; if not, the caller gets the fact itself.

**Community**

- **Multi-board messaging** — General / Tech / Off-Topic / Sysop, one CSV per board under `data/boards/`. New posts use a multi-line `TextArea`, max 1000 chars. A registered name sees the number of its unread messages next to each board.
- **Mail** (Messages > Mail…, `F7`) — private letters between registered names: Write, Reply, Delete. **Feedback to the Sysop…** is a letter anyone with a name can write; every sysop reads it. A letter arriving during a call rings the bell. The Discord feed gets only that feedback came, never what it says.
- **Oneliners** (Messages) — a wall of one-line messages, 64 characters at most; a name is needed, Anonymous cannot write. The newest run along the bottom of the dashboard.
- **Live chat** — broadcast hub, ~1 Hz polling, history replay on join; C64 callers are in it too.
- **IRC #teletypegames** — a read-only window on our channel at Libera.Chat, with how to join it.
- **Voting Booth** (Messages) — the polls of `lib/content/polls.yml`; one is filled from the catalog (your favourite Teletype Games title), one from the doors. Results as bars; a name votes and can change its vote.
- **Page the Sysop** — once a call: the bell, a line in the live chat and on Discord; with no sysop on line it offers to leave a letter.
- **Registered names** — **You > Register…** ties the name you logged in with to a password; from then on that name asks for it. A profile (signature / location / homepage / notes) belongs to a registered name.
- **Nodes** — every caller gets the lowest free node; **People > Who is Online** lists node, name, what the caller is doing (the top window, or the door) and the time on line.
- **Hall of Fame**, **User Listing**, **Team** (People), **Your Stats** (You) — the trophy case (a gold, a silver and a bronze cup for the top callers, the top posters and the Trivia scores, the rest under the case); the registered names with their calls; the members of Teletype Games with their mottos; your own numbers.
- **Last callers** — see *Keeping the bots out* below.
- **Sysop console** — stats and broadcast, for names in `TELETYPE_BBS_SYSOPS` that logged in with their password.
- **Discord feed** — new board posts and sysop broadcasts go to the `TELETYPE_BBS_DISCORD_WEBHOOK` webhook, with mentions disabled.

**Doors** — programs the BBS hands the telnet line to, and takes it back from when they exit ([rubbs](https://wiki.teletypegames.org/engines/rubbs)' `BBS::Door`). Only the programs that live here are doors. **Doors > Games Room…** shows them as the five stations at the back of the clubhouse, a lamp burning over each one somebody is in; **Doors > Door Lobby…** lists them with what each one is, the screen it needs and who is inside.

- **SERMO** — a dual machine running SERMO, from the Neumatronic universe ([sermo-bbs](https://git.teletypegames.org/bbs/sermo-bbs), pulled in as the `sermo` gem): type a command, or just talk to it; `EXIT` returns to the BBS. What you say in words goes to its Lapis-ACP, a small local model (Qwen3.5 0.8B) with a persona from the 1977 canon; it is slow, short-spoken and sometimes wrong, on purpose and otherwise.
- **Commodore 64** and **Commodore Plus/4** — the machine at its `READY.` prompt (blue C64 screen, grey Plus/4 screen, 40 columns) with a small BASIC V2: `10 PRINT CHR$(205.5+RND(1)); : GOTO 10` draws the maze, any key is RUN/STOP. The disk holds our games for that machine: `LOAD"$",8` then `LIST` shows the directory (block counts from the real `.prg` sizes in the FTP server's `/WARP`, as the catalog API carries no sizes), `LOAD"NAME",8` (wildcards work) loads a game, `LIST` shows it and `RUN` prints its card with the catalog link. The Plus/4 also knows `DIRECTORY` and `DLOAD`; `SYS 64738` resets the C64; `EXIT` returns to the BBS.
- **Chat of Ra** — you are the worker sealed in the pyramid of *Blessing of Ra*, and the sun god answers from above. Free words go to the model as Ra; `RIDDLE` asks a riddle of the pyramid, which the code checks (`HINT`, `SKIP`); solve three and Ra blesses you. `GAME` tells where the game is.
- **TTG Trivia** — a door game of the old kind: ten questions about Teletype Games and the old days, 20 seconds each, A–D; a quick answer is worth more and three right in a row earn a streak bonus. Some questions are made from the catalog and the team, the rest come from `lib/content/trivia.yml`; the best ten games are its hall of fame.

**Technical**

- **xterm mouse** — clickable menus, buttons and list items, wheel-scroll lists.
- **Idle disconnect** at 10 minutes.
- **Persistent state** — boards, last-callers log, profiles, accounts, mail, read marks, ballots and Trivia scores are CSV files under `data/`, a Docker volume, so they survive restarts.

## The C64 face

A Commodore 64 (CCGMS, StrikeTerm, SyncTERM in C64 mode, or a C64 behind a WiFi modem) gets the board in PETSCII, 40×25. The **pictures** (the entrance, the main menu, the town map, the games room, the trophies, the room cards, leaving) are drawn in the C64's uppercase/graphics set, the whole screen once and then only what changes; the **reading screens** (posts, letters, the chat, the bulletins, the Master) stay in the lowercase set. The main menu is the clubhouse: the house at the top, lit from the same scene as the modern face, who is calling and what comes next, and the rooms as a cursor menu: `M` Cork board, `E` Mailbox, `O` Graffiti wall, `L` Sofa chat, `I` Radio (IRC), `P` Ring the bell, `U` Notice board, `D` Workshop, `C` Guestbook, `H` Trophies, `V` Ballot box, `S` You, `R` Games room, `N` Town map, `T` Ask the bar (the TTG Master), `Q` Leave; `?` help, `Y` system info. A reading room shows its card once a call. In the games room the C64 and the Plus/4 open; SERMO, Chat of Ra and TTG Trivia need 80 columns and are on the modern face. Our games come to a C64 by XMODEM from the [WarpEngine BBS](https://wiki.teletypegames.org/services/warp-engine-bbs).

`*` swaps the pictures for the old menu of plain text and back; a caller whose name comes in capitals gets it at once, as UltimateTerm (the C64 Ultimate's terminal) in its ANSI mode swaps the case and cannot show the graphics.

## The clubhouse

The board is the clubhouse of the network: not a library and not a store — those are the other buildings of the town —, but the place where a caller sits down, signs the guestbook, sees who is in, leaves a note and plays a game at the back. Every big picture shows something of the board's own data (the nodes, the chat, the mail, the new posts, the doors in use, the guestbook, the events, the wall), the same on both faces; nothing is asked of the outside world, and the town map is static.

| Menu (modern) | Room (C64 key) | Live in the picture |
|---|---|---|
| the logon | the entrance: door, lamp, bell, guestbook | the last three guests, the entry number, the coats on the rack (the nodes) |
| Board > Dashboard | the clubhouse from the street | a lit window a node, the door and the lamp, chimney smoke (a chat line in the last minute), the mailbox flag and count |
| Messages > Boards… | the cork board (`M`) | the new notes |
| Messages > Mail… | the mailboxes (`E`) | the flag on the mailbox |
| Messages > Oneliners | the graffiti wall (`O`) | the wall under the house |
| Messages > Live Chat | the sofa corner (`L`) | the smoke |
| People > Who is Online, Last Callers | the guestbook (`C`) | — |
| People > Hall of Fame | the trophy case (`H`) | the names on the cups |
| Board > Bulletins…, Dev Log | the notice board (`U`), the workshop (`D`) | — |
| Board > BBS Network | the town map (`N`) | static |
| Doors > Games Room… | the games room (`R`) | a lamp over each station in use |
| Help > Ask the TTG Master | the bar (`T`) | — |
| Log off | leaving (`Q`) | the lamps go out, the coat ticket |

The house follows the time of day in Budapest (dawn, day, dusk, night) and the season: snow from December to February, pumpkins in the last week of October, fireworks on New Year's Eve, bunting on the days of a game jam.

![The dashboard: the clubhouse from the street](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-dashboard.png)

![The entrance with the guestbook](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-entrance.png)

![The town map: Board > BBS Network](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-town-map.png)

![The games room: Doors > Games Room](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-games-room.png)

![The trophy case: People > Hall of Fame](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-trophies.png)

![Leaving: the lamps go out](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-leaving.png)

![The seasons on the house: snow, pumpkins, fireworks, bunting](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-seasons.png)

On the C64 the same rooms, drawn separately in PETSCII:

![The C64 main menu](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-menu.png)

![The C64 entrance](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-entrance.png)

![The C64 town map](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-town-map.png)

![The C64 games room](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-games-room.png)

![The C64 trophy case](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-trophies.png)

![Leaving on the C64](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-leaving.png)

![The seasons on the C64 house](https://wiki.teletypegames.org/wiki-assets/teletype-bbs/clubhouse-c64-seasons.png)

**The pictures** are [rubbs](https://wiki.teletypegames.org/engines/rubbs)' `BBS::Art` YAML under `lib/content/art/`, drawn twice, separately for each machine: `modern/` in code page 437 and 256 colours, `c64/` in the C64's uppercase/graphics set. The places the board fills from its data are the hotspots of a picture; the seasons are layers, one for each time of day. rubbs' `art-preview` checks a picture while it is drawn (ANSI on the terminal, the PETSCII bytes, a C64 screenshot). **The town map** reads `lib/content/network.yml`: every board with its name, port, building, colours and the place of its building; a new board is a row there and its two buildings (`building_ID.yml`, 12×4 and 3×3).

**The C64 line is slow**, so the pictures have budgets, measured with `bin/c64-bytes`: the main menu 1105–1123 bytes at every time of day and season (at most 1.2 KB), a move of its bar 146–205, a puff of smoke about 60, the entrance about 1.1 KB, the town map 1000 (a step 161–209), the games room 770, the trophy case 609, a room card 231–265, leaving 570 with the lamps going out in 29–78 bytes each.

## Keeping the bots out

Port 2323 is open to the internet, so telnet password-guessing bots call every few seconds and type `root`, `admin` and the like as their name. Until 2026-10-20 all of them landed in the last-callers list. Now:

- a call shows up as online, and is logged as a last caller, only if the terminal reported its window size (telnet NAWS) — real clients and bbsweb do, the bots do not;
- a call is logged when it ends, and only if it lasted at least 10 seconds;
- a name must start with a letter or digit and contain only letters, digits, space, `.`, `_` and `-`; anything else (`GET / HTTP/1.1`) becomes Anonymous.

# Menus & keys

| Menu | Items |
|---|---|
| **Board** | Dashboard · Bulletins… · Dev Log · System Info · BBS Network · Log off |
| **Messages** | Boards… · New Post… · Mail… · Oneliners · Live Chat · IRC #teletypegames · Voting Booth · Feedback to the Sysop… · Page the Sysop |
| **People** | Who is Online · Last Callers · User Listing · Hall of Fame · Team |
| **Doors** | Games Room… · Door Lobby… · SERMO · Commodore 64 · Commodore Plus/4 · Chat of Ra · TTG Trivia |
| **You** | Your Stats · Profile… · Register… · Sysop Console (logged-in sysops only) |
| **Help** | Ask the TTG Master… · What is coming up? · Where do I start? · Where are the games, files, wiki? · Which doors are there? · New to BBSes? · Keys · About |

Every item has a hint: while it is highlighted, the bottom line tells what it does.

| Key | Action |
|---|---|
| `Alt+letter` | Open the matching top menu |
| `F10` | Open the leftmost menu |
| `F1` | Ask the TTG Master |
| `F2` | Message Boards |
| `F3` | Quick post |
| `F4` | Chat |
| `F7` | Mail |
| `Alt-X` | Log off |
| `Tab` / `Shift-Tab` | Move focus inside a window |
| `Enter` | Activate the focused button / submit |
| `F5` / `Alt-Enter` | Full screen and back, for the windows with much to read; also the `[↑]` / `[↕]` gadget or a double click on the title bar |
| `F6` / `Shift-F6` | Bring the next / previous window to the front; a click on a window does it too |
| `Alt-1` … `Alt-9` | Bring the window with that number (on the right of its top frame) to the front |
| `Ctrl-F5` | Move the window with the arrows, size it with Shift+arrows (Tab switches), Enter ends (F6 too while it is the only window); with the mouse, drag the title bar or the `┘` corner |
| letter / `Alt+letter` | Press the window's button with that hotkey (Alt in a text field) |
| `Esc` | Close the top window or menu |

# Configuration

Copy `env-example` to `.env`:

| Variable | Default | Description |
|---|---|---|
| `BBS_PORT` | `2323` | TCP port. |
| `TELETYPE_BBS_SYSOPS` | empty | Comma-separated sysop names. Their accounts are created only with `bin/account`. |
| `TELETYPE_BBS_DISCORD_WEBHOOK` | empty | Discord webhook for new posts and sysop broadcasts; empty = off. |
| `TELETYPE_BBS_ACCOUNTS_PATH` | `data/accounts.csv` | Registered names, salted PBKDF2-SHA256 hashes, file mode 600. |
| `TELETYPE_BBS_BOARDS_PATH` | `data/boards` | Per-board CSV files. |
| `TELETYPE_BBS_MESSAGES_PATH` | `data/messages.dat` | Legacy single-board file; migrated into General on first run. |
| `TELETYPE_BBS_LAST_CALLERS_PATH` | `data/last_callers.csv` | Finished calls. |
| `TELETYPE_BBS_PROFILE_PATH` | `data/profiles.csv` | User profiles. |
| `TELETYPE_BBS_ONELINERS_PATH` | `data/oneliners.csv` | The oneliners wall. |
| `TELETYPE_BBS_MAIL_PATH` | `data/mail.csv` | Private mail and feedback, file mode 600. |
| `TELETYPE_BBS_LAST_READ_PATH` | `data/last_read.csv` | How far each registered name has read each board. |
| `TELETYPE_BBS_VOTES_PATH` | `data/votes.csv` | The Voting Booth's ballots. |
| `TELETYPE_BBS_TRIVIA_SCORES_PATH` | `data/trivia_scores.csv` | TTG Trivia games. |
| `TELETYPE_BBS_FTP_HOST` | `ftp.teletypegames.org` | The FTP server whose `/WARP` sizes give the Commodore doors the blocks of each game. |
| `TELETYPE_BBS_IRC_SERVER` | `irc.libera.chat` | IRC server of the read-only channel window (TLS); empty = off. |
| `TELETYPE_BBS_IRC_PORT` | `6697` | Its TLS port. |
| `TELETYPE_BBS_IRC_CHANNEL` | `#teletypegames` | The channel the board listens on. |
| `TELETYPE_BBS_IRC_NICK` | `ttgbbs` | The board's nick there; taken at login → `ttgbbs_`. |
| `TELETYPE_BBS_IRC_PASSWORD` | empty | NickServ password of the nick (SASL PLAIN); empty = no login. |
| `SERMO_LLM_URL` | set by compose | SERMO's model, `http://llm:8080`; empty = canned replies only. |
| `SERMO_LLM_MODEL` | set by compose | The model's name in the [model service](https://wiki.teletypegames.org/infrastructure/llm), `qwen3.5-0.8b`. |
| `SERMO_LLM_API_KEY` | empty | SERMO's key to the [model service](https://wiki.teletypegames.org/infrastructure/llm); without it SERMO answers with canned replies. |
| `TELETYPE_BBS_LLM_URL` / `_MODEL` / `_API_KEY` | SERMO's | The model of Ra and the TTG Master; unset or empty falls back to the `SERMO_LLM_*` value. |

## Sysop accounts

A name in `TELETYPE_BBS_SYSOPS` cannot be registered over telnet, so nobody can claim it first. Create the account, or reset any password, from the server shell:

```bash
docker exec -it teletype-bbs bin/account Tasi
```

# Running

```bash
docker compose up --build     # or, with Ruby 3.x: bundle install && ruby bbs.rb
telnet localhost 2323
```

Compose starts one container, `teletype-bbs`. The model behind SERMO, Qwen3.5 0.8B, runs in the server's shared [model service](https://wiki.teletypegames.org/infrastructure/llm), reached as `http://llm:8080` on the `interstack` network; until it answers, SERMO uses canned replies. `docker-compose.dev.yaml` keeps the model next to the BBS instead: a `teletype-bbs-acp` container with llama.cpp's `llama-server`, no key.

## Doors

A door is one entry of `TeletypeBBS#doors` (`lib/domain/teletype_bbs.rb`): its name, the program, the label with its hotkey, the narrowest screen it draws for, and three texts (`tag` for the C64's list, `hint` for the statusbar, `about` for the Door Lobby). The modern face declares them all, and its Doors menu lists them by itself; the PETSCII face offers the ones of 40 columns.

```ruby
Door.new(name: :c64, program: Commodore.os(Commodore::C64, games: @games, sizes: @warp_sizes),
         label: '&Commodore 64', cols: 40, tag: 'c64 + our games',
         hint: 'A Commodore 64 at READY., with our C64 games on its disk: LOAD"$",8 lists them',
         about: 'A Commodore 64 at its READY. prompt, with a small BASIC V2. …')
```

A door is a `BBS::FakeOS` definition (SERMO, the Commodores) or a callable. The `sermo` gem is pinned to a revision in `Gemfile.lock`; the entrypoint updates only rubbs on start. After a change in sermo-bbs, raise it with `bundle lock --update sermo` and redeploy.

## Characters

Ra and the TTG Master run on Qwen3.5 0.8B in the [model service](https://wiki.teletypegames.org/infrastructure/llm), through [rubbs](https://wiki.teletypegames.org/engines/rubbs)' `BBS::AI`. A model this small is good at a short reply in a voice and bad at facts, so the code keeps the facts: Ra's riddles and the game's address come from the code, `deflect` rules answer what the model gets wrong however it is asked (code, poems, "are you a bot"), and the Master's wording is checked against the facts before it is shown. The Master's knowledge (`lib/characters/master_knowledge.yml`, and `master_knowledge_c64.yml` for the C64 face) names a menu path only for what is on this board, and the board and port for what another board carries.

Personas are tuned by measuring, not by single replies: `bin/persona-eval ra|master|master_c64 3` asks the eval questions (`lib/characters/eval/`) several times and counts the slips: out of character, markdown, too long, and for the Master a miss (a wrong menu path or a lost fact).

```bash
docker exec teletype-bbs bin/persona-eval master 3
```

# Project structure

```text
bbs.rb                       entry point: the terminal question, then a face
bin/account                  create an account / reset a password
bin/persona-eval             count a character's slips over many runs
bin/c64-bytes                the bytes of the C64 pictures on the line
lib/
  domain/teletype_bbs.rb     the board: services wired to their stores, the doors,
                             the network list, what a call does across services
  domain/
    repository/              nodes, boards, catalog, site (events, members), accounts,
                             last callers, profiles, oneliners, FTP (file sizes),
                             Gitea, mail, read marks, votes, the network (town map);
                             http_json (GET + 5-min cache)
    service/                 online, board, games, site, account, chat, IRC, last callers,
                             profile, oneliner, WARP sizes, dev log, discord_notifier,
                             mail, voting, taglines, network, scene (what the
                             clubhouse pictures show, for both faces)
    model/                   value objects (MessageModel, GameModel, …)
  doors/commodore.rb         the C64 and Plus/4 doors; commodore/basic.rb is their BASIC
  doors/ra.rb                Chat of Ra
  doors/trivia.rb            TTG Trivia
  content/                   polls, Trivia questions, taglines, bulletins, network.yml
  content/art/               the clubhouse pictures: modern/ (cp437) and c64/ (PETSCII)
  characters/                Ra and the TTG Master: personas, riddles, knowledge, eval questions
  ui/arts.rb                 loads and keeps the pictures
  ui/modern.rb               the modern face: modem, entrance, windows, menus, doors
  ui/modern/                 the dashboard, the picture rooms (town map, games room),
                             the entrance, leaving, cards, trophies, the formatters
  ui/petscii.rb, ui/petscii/ the C64 face: entrance, the clubhouse pictures
                             (petscii/clubhouse.rb), the reading sections
data/
  boards/<id>.csv            per-board messages (auto-created)
  last_callers.csv           finished calls
  profiles.csv               user profiles
  accounts.csv               registered names
  oneliners.csv              the oneliners wall
  mail.csv, last_read.csv,
  votes.csv, trivia_scores.csv
```

## Repository

https://git.teletypegames.org/bbs/teletype-bbs

'; var prevLevel = 2; for (var i = 0; i < headings.length; i++) { var h = headings\[i\]; var text = h.textContent.trim(); var slug = text.toLowerCase() .replace(/\[áàâä\]/g,'a').replace(/\[éèêë\]/g,'e').replace(/\[íìîï\]/g,'i') .replace(/\[óòôöő\]/g,'o').replace(/\[úùûüű\]/g,'u') .replace(/\[^a-z0-9\]+/g, '-').replace(/^-|-$/g, ''); if (!slug) slug = 'heading-' + i; if (used\[slug\]) { slug += '-' + i; } used\[slug\] = true; h.id = slug; var level = parseInt(h.tagName.charAt(1)); var cls = level > 2 ? ' class="toc-child"' : ''; html += '- [' + text + '](#'%20+%20slug%20+%20')
'; } html += '
'; toc.innerHTML = html; // Scroll-spy: highlight current heading var links = toc.querySelectorAll('a'); var ids = \[\]; for (var j = 0; j < links.length; j++) ids.push(links\[j\].getAttribute('href').slice(1)); function updateActive() { var current = ''; for (var k = 0; k < ids.length; k++) { var el = document.getElementById(ids\[k\]); if (el && el.getBoundingClientRect().top <= 80) current = ids\[k\]; } for (var m = 0; m < links.length; m++) { links\[m\].parentNode.classList.toggle('active', links\[m\].getAttribute('href') === '#' + current); } } window.addEventListener('scroll', updateActive, { passive: true }); updateActive(); })();

---

## Navigation

- Parent: [Services](https://wiki.teletypegames.org/services.md)
- Previous: [Discord Thread Scheduler](https://wiki.teletypegames.org/services/statusbot.md)
- Next: [Teletype Orbit](https://wiki.teletypegames.org/services/teletype-orbit.md)
