Repository navigation
Accessibility
TL;DR: Blind players use the game with screen readers, so no fact may live only in color, an image or an ASCII drawing. A single switch,
config screenreader, tells the engine and scripts to print words instead of decoration. Every visual you add needs a linear text twin. Use when: you add a table, a map, a bar, a color-coded marker, a frame or any layout that a speech engine would read as noise. Source of truth:dreamland_code/plug-ins/output/screenreader.cpp(uses_screenreader),dreamland_code/plug-ins/output/mudtags.cpp(visibility tags),dreamland_world/helps/help.xml(help 2132),mudjs/src/components/terminal.jsxVerified: 2026-11-02 against dreamland_code 88da8302, dreamland_world 43880467, mudjs 990bf6d
About 30% of active players are blind (maintainer estimate, unverified). The game is fully playable by ear. That is a design requirement, not a favor. Accessibility problems are bugs.
Players turn the mode on with:
config screenreader yes
The in-game article is help 2132 (help screenreader). It lists what the mode changes:
- Items and mobs lose the English name in parentheses.
- Colored items get an aura word such as (Bright) in place of the color.
- Random weapons show tier words.
- Most ASCII pseudo-graphics become text descriptions.
- After each experience gain the game says how many points remain to the next level.
Details of the setting:
- It is stored for the account, not per character. The account-wide settings are
screenreader,fightspam,skillspamandnoweaponspam(config_is_account_wideinplug-ins/comm/configs.cpp). - A connection that identifies its terminal type as Lyntin counts as a screen reader even with the setting off.
- The config entry in
dreamland_world/config/settings.jsoncarries the label and hint in all three languages.
Players are also advised to turn colors off (config colour no), since color codes add nothing for speech.
In C++, ask the engine:
#include "screenreader.h"
if (uses_screenreader(ch)) {
// linear text
} else {
// table, bar, drawing
}Many places treat "screen reader on" and "colors off" the same. A viewer with color off cannot see a color cue either, so the pattern is:
if (!uses_screenreader(ch) && ch->getPC()->getConfig().color)
return; // the colors are enough, say nothing extraformat_screenreader_flags and look_targets_hint in plug-ins/comm/look.cpp follow it.
In Fenia, read the character field. It already folds in the terminal check:
if (ch.screenreader)
ch.ptc("Linear text.");
else
ch.ptc("A frame or a table.");The field is read-only. The raw bit is also available as .tables.config_flags.screenreader, but it misses the terminal-type case, so prefer ch.screenreader. ch.ptc(msg) prints a raw string to a character. Look other methods up through Fenia-API.
Use these as models.
| Place | Plain-text twin |
|---|---|
Item names in rooms and inventory (look.cpp) |
A color-coded tier becomes a word: (Legendary), (Epic), (Rare), (Uncommon), (Bright) |
Jeweler sockets (look.cpp) |
Colored stars on the name become (Socketed) |
Room descriptions (look.cpp) |
A list of the extra descriptions you can examine, including hidden ones |
Social list (csocials.cpp) |
One social per line instead of a table |
Calendar (weather.cpp) |
Today's date, active bonuses and upcoming bonuses as sentences instead of a grid with a legend |
| Mudlet package | The side panel can be hidden with dl hide, and the game text carries every fact on its own |
Inside any string a player reads, a span can be limited to a kind of viewer. Each span is closed with {Ix.
| Tag | Shown to |
|---|---|
{Is |
Screen reader users only |
{IS |
Everyone who is not using a screen reader |
{Iw |
Web client only |
{IW |
Telnet only |
{Ii |
Immortals only |
A span prints when the viewer has the matching bit, so the pair {IS (drawing) and {Is (words) gives each audience its own version.
The trap: {x is a total reset. It also clears the visibility state, so everything after a {x inside a span prints to every viewer. Two rules follow:
- Keep color resets and other
{xoutside the span, and gate only the value. - Do not gate a line assembled by a helper that emits its own
{x. The first{xends the gate, and the rest of the line leaks to everyone.
A clickable link inside a span is closed with {hx, not {x. A link already behaves correctly for web and telnet, so wrap it only when the wording around it differs. More on tags: Text-Markup.
- No fact lives only in color. Pair every color cue with a word, as the aura words above do.
- No ASCII art as the only path. Frames, bars, grids and maps get a screen reader branch that reads as sentences or one item per line.
- Prefer one item per line over a table. Speech engines read columns across, and the result is noise.
- Keep text short. Every extra line is one more thing to listen to.
- Never rely on a graphic panel alone. The Mudlet panel can be hidden and the game text still carries every fact. Follow that.
- Wiki and docs: every image gets alt text, and no information is carried only by an image.
The main text window of the web client is an aria-live="polite" region that announces additions only (terminal.jsx). Decorative layers (terminal-glow, terminal-flash) are aria-hidden. Keep new decorative elements hidden from assistive technology the same way, and give interactive controls labels.
The line editor (ed) works in a plain telnet stream and has no cursor addressing, so it works with a screen reader. In the web client, webedit opens a text buffer (unverified for screen reader users). The editor is documented on OLC-Line-Editor.
- Log in over telnet or the web client.
- Run
config screenreader yesandconfig colour no. - Walk through the feature with the screen off, or with your speech engine running.
- Check that each message still makes sense read aloud once, with no leftover tag fragments.
Start here
Get running
Contribute
- Contribute
- Contributing Workflow
- Code Style
- Accessibility
- Writing Player Text
- Game Design Principles
Build areas
- Building
- OLC
- OLC Rooms
- OLC Mobiles
- OLC Objects
- OLC Resets
- OLC Line Editor
- OLC Other Editors
- Area Format
- Area Quests
- Mob Forms and Parts
Fenia
- Fenia
- Fenia Language
- Fenia Triggers
- Fenia Gotchas
- Fenia API
- Fenia Scripts
- Fenia Behaviors
- Fenia Skills and Spells
- Fenia Cookbook
- Fenia Grammar
Engine
- Engine Architecture
- Engine Time and Pulses
- Output Format
- Mechanics Combat
- Mechanics World
- Data Configs
- Item Power
Localization
Clients
More