---
title: TTGWIKI
url: 'https://wiki.teletypegames.org/dos/ttgwiki'
markdown: 'https://wiki.teletypegames.org/dos/ttgwiki.md'
lang: en
date: '2026-10-14'
description: 'TTGWIKI reads the public pages of this wiki on DOS (TTGWIKI.EXE, C++, Open Watcom, 8086 code, mTCP) and on Windows 95 and later (TTGWIKIW.EXE, Winsock, in a console window). A DOS machine cannot speak HTTPS, so the server side of the same repository exports the wiki as plain text files, and the Te…'
taxonomy:
  tag:
    - howto
---

# TTGWIKI

> TTGWIKI reads the public pages of this wiki on DOS (`TTGWIKI.EXE`, C++, Open Watcom, 8086 code, mTCP) and on Windows 95 and later (`TTGWIKIW.EXE`, Winsock, in a console window). A DOS machine cannot speak HTTPS, so the server side of the same repository exports the wiki as plain text files, and the Teletype Games [FTP server](https://wiki.teletypegames.org/infrastructure/ftp-server) shares them over anonymous, read-only FTP, next to the [DOSINST](https://wiki.teletypegames.org/dos/dosinst) store.
> 
> A page is downloaded when it is read and kept on the disk, so it can be read again offline; `F6` downloads them all. The export follows the wiki within 15 minutes.

- **Repository:** [git.teletypegames.org/dos/ttgwiki](https://git.teletypegames.org/dos/ttgwiki)
- **Export:** `ftp://ftp.teletypegames.org/WIKI` (anonymous, read-only)
- **Install:** `TTGWIKI` and `TTGWIKIW` from the [DOSINST](https://wiki.teletypegames.org/dos/dosinst) store, or from the [releases](https://git.teletypegames.org/dos/ttgwiki/releases): DOS: [TTGWIKI-v0.2.0.zip](https://git.teletypegames.org/dos/ttgwiki/releases/download/v0.2.0/TTGWIKI-v0.2.0.zip) · Windows 95 and later: [TTGWIKIW-v0.2.0.zip](https://git.teletypegames.org/dos/ttgwiki/releases/download/v0.2.0/TTGWIKIW-v0.2.0.zip)

![TTGWIKI reading a page in DOSBox](https://wiki.teletypegames.org/wiki-assets/ttgwiki/screenshot.png)

---

# What it does

- **The contents** list the pages as a tree with the date of their last change. Typing searches the titles, ignoring case and accents (`kezdo` finds *Kezdőlap*). `F2` switches between English and Hungarian; a page without a translation is shown in the language it is written in, marked `[en]`.
- **The reader** shows a page as the wiki has it: headings, lists, code blocks, quotes and tables, in colors. `Tab` / `Shift+Tab` select the links and the status line tells where they go, `Enter` follows a link to another page, `Backspace` goes back. A web link is only shown: open it on another machine.
- **Offline**: a page read once stays in `CACHE\` next to the executable. When the server cannot be reached, TTGWIKI says so and reads from the disk. A refused connection is reported at once on master; 0.2.0 still waits out mTCP's 10-second connect timeout first. `F6` (or `TTGWIKI SYNC`) downloads every page of a language.
- **Fresh**: at start and on `F5` TTGWIKI reads `WIKI.INI` from the server. When the export has a new generation, the new page list comes and the pages that changed are deleted from the disk, so they are downloaded again when they are read. Nothing else is downloaded.
- **Printing**: `TTGWIKI SHOW /dos/gmenu > PRN` prints a page as plain text.
- **Code pages**: `CODEPAGE=852` in `TTGWIKI.CFG` shows every Hungarian letter; in 437 (the default) the missing ones become a near letter (ő → ö).

```
TTGWIKI                    browse the wiki
TTGWIKI SYNC         download every page of a language
TTGWIKI SHOW route   print a page
```

# How it works

```
 wiki.teletypegames.org (Grav)
        │  /custom/sitemap.json, /custom/page.json (inside the wiki's docker network)
        ▼
 exporter (server/export.py)   at start, then every 15 minutes
        │  WIKI.INI, EN/INDEX.TXT, EN/FILES.LST, EN/P0000001.TXT, ... HU/...
        ▼
 FTP (infra/ftp-server)        ftp://ftp.teletypegames.org/WIKI
        │
        ▼
 TTGWIKI.EXE / TTGWIKIW.EXE    CACHE\EN\..., CACHE\HU\...
```

- The **exporter** reads the same JSON endpoints as the [TTG Wiki BBS](https://wiki.teletypegames.org/services/wiki-bbs), renders every public page's HTML as text (`server/render.py`) and writes a folder per language. A restart exports at once. A new export is written only when something changed; the language folders are swapped in with renames and `WIKI.INI` comes last with the next generation number. A failed run (the wiki down) changes nothing.
- **Private pages never leave the server**: they are dropped from the sitemap, and without a token Grav does not give out their text anyway.
- **A page file** has header lines (`TITLE=`, `URL=`, `L=<n> <target>` for each link), then lines of at most 78 characters, UTF-8. Control bytes that take no column mark the styles (`01h c`) and the links (`02h n 03h` … `04h`); every line is complete in itself, so the reader can start anywhere. TTGWIKI turns the text into the code page of the screen, one byte for every character, and reads a page a line at a time from the disk (the longest page has nearly 3000 lines).
- **Ids stay**: a page gets a number once (`P0000123.TXT`), read back from `INDEX.TXT` on every export; the two languages share it, so `F2` shows the same page.
- `FILES.LST` has the CRC-32 and the size of every file, in DOSINST's format: every download is checked.

# The server

The `ttgwiki` stack on vps.teletype.hu (`/srv/stacks/ttgwiki`, `compose.yaml`) is the exporter alone. It writes the `WIKI` folder of the [FTP server](https://wiki.teletypegames.org/infrastructure/ftp-server) (`/srv/stacks/ftp-server/root/WIKI`), which shares it on port 21: anonymous, read-only, passive mode only. Since 0.2.0 TTGWIKI connects there by default (`PORT=21`, `PATH=/WIKI`); 0.1.0 used port 2121, which is closed. The exporter joins the network of the `wiki-pages` stack. A push to master that changes the server side deploys it from the pipeline.

# Building and tests

Open Watcom v2, as for DOSINST: `SOURCE/build.sh` builds both executables. The client is in layers on [DOSLIB](https://wiki.teletypegames.org/dos/doslib) (which got the code pages 437 / 852 and seeking in files for it). The pipeline runs the server side's tests (the renderer, the exporter on a fake wiki), the client's unit tests on the host, and two end-to-end tests: the exporter writes a small export, the FTP server shares it, and TTGWIKI runs in a headless DOSBox Staging (printing, downloading, a new export, code page 852, offline, browsing with scripted keys) and TTGWIKIW under Wine. The steps are commands of the [dos-tools](https://wiki.teletypegames.org/platforms/dos) builder image (`git.teletypegames.org/build/dos-builder`), with the toolchain preinstalled; the repo holds only the `platform: dos` marker and its `metadata.json`. A `vX.Y.Z` tag publishes the release to the catalog, and the [WarpEngine](https://wiki.teletypegames.org/engines/warp-engine) puts both builds into the DOSINST store, its DOS shelf (without `TTGWIKI.CFG`); there is no store step. The deploy of the server side (`.woodpecker/deploy.yaml`) only calls the server's `deploy` user over SSH, with a key bound to one fixed command (`ci-deploy ttgwiki`; `infra/host-config`): the server clones master itself and checks `compose.yaml` against a policy, so the pipeline needs no trusted volumes. Details: the repository's README.

'; 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: [DOS](https://wiki.teletypegames.org/dos.md)
- Previous: [GMENU](https://wiki.teletypegames.org/dos/gmenu.md)
