Classic bug: Messages leak ANSI color and intensity
| Bug ID | GE-BUG-042 |
|---|---|
| Affected versions | Classic 3.2e and published classic message files |
| Status | Verified in message files; superseded in ge-next |
| Fixed in | ge-next 0.01 |
| Primary source | ANSI SGR sequences in the main and help message files |
Summary
Classic GE does not consistently restore its normal bright-white terminal state after displaying colored text. Some complete messages end while red, yellow, or cyan is still selected, causing the following command prompt and any initially uncolored output to inherit that color. Other messages issue an ANSI reset with 0 but never re-enable bright intensity with 1, causing later text to appear dimmer than GE's normal display.
The two symptoms have the same underlying cause: ANSI color is persistent terminal state. Printing a message does not automatically restore the state that was active before it.
ge-next 0.01 replaced and recolored the complete message collection. These individual classic definitions were therefore not repaired one by one; they were superseded by messages designed to set their own colors explicitly.
ANSI state persists across messages
GE uses ANSI Select Graphic Rendition sequences. The relevant parameters are:
| Sequence | Effect |
|---|---|
ESC[0m |
Reset color and intensity to the terminal defaults |
ESC[1m |
Enable bold or bright intensity |
ESC[31m through ESC[37m |
Select a foreground color |
ESC[1;37m |
Select GE's expected bright-white baseline |
The color parameters do not restore intensity. In particular, ESC[37m selects white but does not undo the dimming caused by an earlier ESC[0m. Once a message has reset the terminal, restoring classic GE's usual display requires ESC[1;37m, not merely ESC[37m.
Likewise, changing to yellow with ESC[33m does not automatically end when the message ends. If no later sequence selects white, the next prompt remains yellow.
Standalone game messages that leak color
The following complete definitions in the classic main message file select a non-white color and do not select white before ending:
| Definition | Final color | Context |
|---|---|---|
WARHUP |
Cyan | Announces that a disconnected commander's ship vanished |
DIED |
Cyan | Announces a destroyed ship |
SCAN2 |
Yellow | Reports a scan from beyond scanner range |
SCAN3 |
Yellow | Reports a scan from an unidentified source |
ATTACK6 |
Cyan | Sends a planet-under-attack distress report to its owner |
ATTACK6A |
Cyan | Sends the corresponding alert outside the game |
MOVE4 |
Red | Reports that low neutron flux stopped the engines |
ZAPHIM1 |
Red | Reports damage from the Enforcer Planet |
For example, SCAN3 is effectively:
*** ESC[33m
Sir! We are being scanned by an unknown source bearing %d.
There is no final ESC[37m. The recipient's next command prompt is therefore yellow. MOVE4 and ZAPHIM1 produce the same effect in red, while the broadcast and attack messages leave cyan selected.
This list excludes definitions such as INTRO and ADMENU1B that are deliberately concatenated with later menu fragments before output is complete. A fragment does not need to restore the baseline if the final fragment in the same composed display does so. The messages listed above are emitted as complete notifications and have no such final fragment.
Explicit reset leaves text dim
RNDPHSR, the random phaser-system damage warning, contains both forms of the intensity problem:
ESC[0;1;32m***
ESC[0mThe phaser systems appear to be damaged, Sir!!
Damage Control notified!
The first sequence resets the state and then enables bright green. The second sequence resets it again immediately before the warning text. Nothing after that reset re-enables bright intensity or restores bright white. The body of the warning is displayed in the terminal's normal, non-bright default, and the following prompt inherits that state.
The main-menu EXPLAIN text similarly ends with ESC[0;32m. Its normal menu path immediately prints the separate REPRMT definition, which selects bright green for the menu prompt, so that composition masks the leak during ordinary use. It still demonstrates the same unsafe assumption: the definition resets terminal state without restoring GE's baseline itself.
The classic help database
The problem is systematic in MBMGEHLP.MSG. The help index and all 60 help-text definitions fail to finish with ESC[1;37m.
HLPINDEX begins with ESC[0m, uses bright green for topic names, and ends while red is selected. The prompt following the index is therefore bright red rather than bright white.
Forty-four of the 60 help definitions finish with bright intensity disabled. These are:
HLPSTART HLPGALXY HLPSECTR HLPCOMMU HLPNAVIG HLPPLANT HLPPLAN2
HLPPLAN3 HLPSTRAT HLPBATTL HLPBATT2 HLPBATT3 HLPCYBER HLPSCORE
HLPWORM HLPABA HLPABO HLPATT HLPBUY HLPCLO HLPCLS HLPDEC HLPDES
HLPFLU HLPHEL HLPJAM HLPLOC HLPMAI HLPMIN HLPNEW2 HLPORB HLPPLA
HLPPRI HLPREN HLPSET HLPSCA HLPFRE HLPTRA HLPZIP HLPCLS2 HLPCLS3
HLPTEA HLPSPY HLPJET
Most end with ESC[0m; five end with ESC[0;36m. In either case, the reset has disabled bright intensity and no later 1 restores it.
The remaining 16 definitions restore or retain bright intensity but still end in cyan or green rather than white:
HLPADM HLPHYP HLPIMP HLPMIS HLPNAV HLPNEW HLPPHA HLPREP HLPROS
HLPROT HLPSEL HLPSEN HLPSHI HLPTOR HLPWAR HLPCLS1
Several topics are assembled from more than one definition, such as HLPNEW/HLPNEW2 and HLPCLS1/HLPCLS2/HLPCLS3. Their final parts still leave the completed help display dim. The definition-level list is useful to port authors because each component may be retained, removed, or recombined differently in another implementation.
Gameplay and interface consequences
The defect does not alter simulation state, but it makes the interface depend on whichever message happened to print most recently. Visible effects include:
- a command prompt unexpectedly appearing red, yellow, cyan, or green;
- ordinary white text becoming dim after help or random damage output;
- later messages that assume the bright baseline also appearing dim; and
- inconsistent results when a port, terminal, or frontend initializes ANSI attributes differently.
The behavior can appear intermittent because many later GE messages do select white, and some menu prompts explicitly select bright green. Those later sequences conceal the leaked state rather than correcting the faulty message.
Porting guidance
Ports that preserve the original prose should audit the final ANSI state of each complete output unit. At minimum:
- complete gameplay notifications should restore white before ending;
- any message that uses
0should restore both intensity and color with1;37before returning control to the prompt; and - multi-part displays should restore the baseline in their final emitted fragment rather than blindly adding resets to every intermediate fragment.
This retains the original wording while preventing one message from changing the appearance of unrelated output.
Replacement in ge-next 0.01
ge-next 0.01 was a message-only release that ran on the unmodified classic 3.2e DLL. It introduced a complete reworking of the game messages and color codes. The release notes explicitly describe every message as setting color codes to prevent the original game's fading and other color errors.
Because the collection was replaced as a whole, ge-next did not apply a discrete patch to WARHUP, code>RNDPHSR, every help page, and the other affected classic definitions. The original defects ceased to be present because the replacement messages establish and restore their intended display states. Later ge-next and ge-next32 releases retain that message design.
Home · Play · Reference · Versions & history · Sysop · Development · Classic bugs