---
title: ttg-common
url: 'https://wiki.teletypegames.org/engines/rubbs/ttg-common'
markdown: 'https://wiki.teletypegames.org/engines/rubbs/ttg-common.md'
lang: en
date: '2026-11-03'
description: "ttg-common (repository bbs/common) is where the parts of our boards go that more than one board needs but that are too Teletype Games-specific for rubbs itself: a logo, a house text, the list of the network's boards. rubbs keeps the machinery (a BBS::Splash takes any two drawings); ttg-common brin…"
taxonomy:
  tag:
    - reference
---

# ttg-common

> `ttg-common` (repository `bbs/common`) is where the parts of our boards go that more than one board needs but that are too Teletype Games-specific for [rubbs](https://wiki.teletypegames.org/engines/rubbs) itself: a logo, a house text, the list of the network's boards. rubbs keeps the machinery (a `BBS::Splash` takes any two drawings); `ttg-common` brings ours.

# Using it

```ruby
# Gemfile
gem 'bbs', git: 'https://git.teletypegames.org/engines/rubbs.git'
gem 'ttg-common', git: 'https://git.teletypegames.org/bbs/common.git'
```

```ruby
require 'ttg/common'
```

The board's `Gemfile.lock` pins a revision of both. `devarea/scripts/bbs-lock-bump.sh` moves every board to the latest rubbs, and a board whose lock has `ttg-common` to its latest revision too, in one commit (`Lock rubbs 1.7.0 (75d7375), ttg-common 0.1.0 (16d65b8)`). The first time, add the gem to the `Gemfile` and run `bundle lock --update bbs`.

# What is in it

| Module | What | Used by |
|---|---|---|
| `TTG::Logo` | The Teletype Games logo as two [`BBS::Art`](https://wiki.teletypegames.org/engines/rubbs/art) drawings and as a `BBS::Splash` | every board of the network |

## `TTG::Logo`

```ruby
config.flow = BBS::Terminal.flow(title: 'Teletype BBS', modern: m, petscii: p,
                                 splash: TTG::Logo.splash)
```

After the [terminal question](https://wiki.teletypegames.org/engines/rubbs/commodore) the caller gets the logo, centred, with `PRESS ANY KEY TO CONTINUE` under it; any key or 60 seconds goes on.

| Face | Drawing | Size |
|---|---|---|
| Modern (`TTG::Logo.art(:modern)`) | `lib/ttg/logo/modern.yml`, cp437 half blocks, 256 colours, a colour above and one below in each cell | 66 × 23 |
| Commodore 64 (`TTG::Logo.art(:petscii)`) | `lib/ttg/logo/c64.yml`, petscii-upper quarter blocks, the C64's own colours, one a cell | 33 × 23 |

Both come from the same pixels: `media/LOGOv2/TTG-Logo-Black.png` (132 × 100) halved to 66 × 46, each 2 × 2 block taking its most common colour. The `TELETYPE GAMES` line is the 3 × 5 block font of rubbs with a light green middle row, as on the original. `art-preview lib/ttg/logo/c64.yml --png out.png` (in rubbs) shows the C64 drawing with the real character ROM.

# Adding a part

One module under `TTG` in its own file (`lib/ttg/PART.rb`, its data beside it in `lib/ttg/PART/`), required from `lib/ttg/common.rb`, with a test and a row in the table above and in the README. As in rubbs, everything is RDoc-documented and CI fails below 100%; `rake test` and `rubocop` must be clean.

# Releasing

Bump `ttg-common.gemspec`, commit, tag `vX.Y.Z` (annotated) and push both; the tag pipeline rejects a tag that does not match the gemspec.

'; 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: [RuBBS](https://wiki.teletypegames.org/engines/rubbs.md)
- Previous: [Telnet, session and store](https://wiki.teletypegames.org/engines/rubbs/telnet-and-store.md)
- Next: [Widgets](https://wiki.teletypegames.org/engines/rubbs/widgets.md)
