Classic bug: Filtered broadcast suppresses later recipients

Bug ID GE-BUG-055
Affected versions Classic Galactic Empire 3.2e and published classic source; standard ge-next builds through 0.3.1
Status Verified in source; reproduced in multiplayer testing before correction
Fixed in ge-next 0.3.2
Primary source outprfge(), outwar(), outsect(), and outrange() in GEMAIN.C; cmd_send() in GECMDS.C

Summary

Classic GE can suppress a FILTER-class broadcast for players who have not enabled filtering. When one eligible recipient has SET FILTER ON, rejecting that message clears the shared print buffer. The broadcast continues to higher-numbered user slots, but the text has already been erased. Earlier eligible recipients can receive the message; later ones cannot. This is not an intended effect of the later players' own settings.

Reproduction

  1. Have three players in GE on user slots 0, 1, and 2. Player 0 is the sender. Player 1 enters SET FILTER ON; player 2 leaves SET FILTER OFF.
  2. Player 0 tunes one classic A/B/C preset to HAIL and sends a public message with, for example, SEND A test.
  3. Player 1 correctly does not receive the filtered hail. Player 2 also does not receive it, despite filtering being off.
  4. If player 1 turns filtering off and the sender repeats the hail, player 2 receives it. A recipient visited before the filtered player is unaffected.

The same failure pattern can occur for other FILTER-class messages distributed through a sector or scanner-range broadcast. It does not apply to every message: calls marked ALWAYS are not rejected by this setting, and a recipient must otherwise qualify for that particular broadcast.

Cause

Classic broadcast helpers iterate potential recipients in ascending user-slot order, calling outprfge() with the same formatted print buffer. For a FILTER message whose recipient has filtering enabled, outprfge() calls clrprf() rather than sending the text:

if (class == FILTER && warusroff(shpno)->options[MSG_FILTER] == TRUE) {
    clrprf();
    return;
}

That clears the message for the whole ongoing broadcast, not just this recipient. The loop in outwar(), outsect(), or outrange() still visits later eligible slots, but their output calls no longer have the original message to send. A public hail from classic SEND A, SEND B, or SEND C when that preset is set to HAIL uses outwar(FILTER, ...), making the problem visible in ordinary play.

Correction in ge-next

ge-next 0.3.2 separates individual recipient delivery from buffer cleanup. Its internal sendprfge() decides whether to send to one recipient without clearing a rejected message. The broadcast helpers use that routine for each eligible recipient and call clrprf() only after the broadcast loop finishes. The public outprfge() wrapper still clears after an individual rejected delivery, where no subsequent broadcast recipients depend on the buffer. A recipient's display settings therefore affect only that recipient.

ge-next uses more specific message categories in place of classic's single FILTER switch; that interface change is separate from the shared-buffer correction.

Discovery transcript

Read the multiplayer observation that revealed the broadcast-filter failure.

See also