Developing for ANetBBS
Want to write a door, a web feature, a theme, or hook into messaging?
You're in the right place.
The ten door types
ANetBBS runs door games via ten distinct backends:
- DOS doors (DOSBox-staging) — TradeWars, LORD-DOS, Usurper
- DOS doors (dosemu2, virtual COM1, no FOSSIL) — an alternative to
DOSBox-staging for DOS games that need it specifically - Native Linux doors — any executable, stdio piped
- Synchronet
.jsdoors — realjsexecif installed, otherwise
our built-in Node + Synchronet API shim (~270 functions) - Mystic Pascal
.mps/.mpx— bundled Mystic 1.12 A48 runtime - Mystic Python
.py— fakemystic_bbsmodule - rlogin out-dial — DoorParty / A-Net Online / Synchronet xtrn
- Telnet out-dial — TWGS and other telnet-only remotes, no
pre-auth handshake - Built-in web games — Flask-routed mini-games
- In-browser DOS games — EmulatorJS + dosbox_pure, runs entirely
client-side, no telnet/SSH client needed
See docs/17-development.md for the
deep-dive: drop file formats, token substitution table, working code
examples for each type.
Extending the web app
The web side is Flask + SQLAlchemy + SocketIO. Adding a new
feature is roughly:
- Create a blueprint in
anetbbs/web/myfeature.py - Register it in
anetbbs/web_app.py - Add templates in
anetbbs/templates/myfeature/ - (Optional) Add a nav-bar link in
templates/base.html - (Optional) Add a model class (or a new column on an existing one)
toanetbbs/models.py— see Database below, no migration
command needed for the common case
The whole pipeline is ~50 lines of code for a working feature blueprint.
Database
anetbbs/models.py is the single source of truth for SQLAlchemy
models. There's no alembic/flask db migrate step in normal use —
web_app.py runs an auto-sweep (_lightweight_migrate()) on every
startup: it walks db.metadata.sorted_tables, and for any column a
model declares that the live table is missing, issues a permissive
ALTER TABLE ADD COLUMN (nullable, no default, so it always succeeds
on SQLite). Add a column, restart anetbbs-web, done. See
Architecture for the same mechanism described from the ops side.
A hand-written migration is still the right call for anything
destructive (renaming/dropping a column, backfilling data) — the
auto-sweep only ever adds.
Themes
Themes are DB rows with CSS variable values, edited visually at
/admin/theme-builder/. Add a new built-in theme by tweaking colors
in the builder, then add the resulting values to the default-theme
seed block in _create_default_data() in anetbbs/web_app.py
(there's no separate seed_data.py — it's all in web_app.py).
Real-time features
Flask-SocketIO is wired up in web_app.py. The Web Terminal and MRC
client are both reference implementations of a feature that spawns a
background eventlet greenthread, pumps bytes between a backend socket
and the browser, and handles reconnect.
Echomail / FidoNet networks
Pollers live in anetbbs/echomail/{binkp,qwk,tic}.py. Adding a new
network type is one new module + one new EchomailNetwork.protocol
discriminator.
Where to ask questions
- Email —
a-net-online@proton.me - Open a GitHub issue at
anetonline/anetbbs - This wiki — anyone with edit rights can expand the
Development page and create child pages
If you ship something cool, PR it back and we'll bundle it with the
next alpha.
Reference
The authoritative deep-dive is at docs/17-development.md.
This wiki page is the lightweight community-editable companion.