From 5f12a4f841725a192b27d21aa19db9c64fb1b9e9 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 10 Feb 2026 14:36:42 -0500 Subject: [PATCH] Suppress upper window writes in MudScreen to fix Lost Pig output V5+ games write room names to the upper window (status line) via select_window(1). Since select_window was a no-op, status line text leaked into the main output buffer, causing ">Outside" on prompt lines. Track the active window and only buffer writes to window 0 (lower). --- src/mudlib/zmachine/mud_ui.py | 8 +++++--- tests/test_embedded_if.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/mudlib/zmachine/mud_ui.py b/src/mudlib/zmachine/mud_ui.py index a569a54..cfa4ae5 100644 --- a/src/mudlib/zmachine/mud_ui.py +++ b/src/mudlib/zmachine/mud_ui.py @@ -21,6 +21,7 @@ class MudScreen(zscreen.ZScreen): def __init__(self): super().__init__() self._buffer = [] + self._active_window = 0 # 0=lower (main text), 1=upper (status line) self._columns = 80 self._rows = zscreen.INFINITE_ROWS self.features = { @@ -31,7 +32,8 @@ class MudScreen(zscreen.ZScreen): } def write(self, string): - self._buffer.append(string) + if self._active_window == 0: + self._buffer.append(string) def flush(self) -> str: result = "".join(self._buffer) @@ -39,10 +41,10 @@ class MudScreen(zscreen.ZScreen): return result def split_window(self, height): - logger.debug(f"split_window({height}) - no-op") + logger.debug(f"split_window({height})") def select_window(self, window): - logger.debug(f"select_window({window}) - no-op") + self._active_window = window def set_cursor_position(self, x, y): logger.debug(f"set_cursor_position({x}, {y}) - no-op") diff --git a/tests/test_embedded_if.py b/tests/test_embedded_if.py index e6d1e13..caea6f9 100644 --- a/tests/test_embedded_if.py +++ b/tests/test_embedded_if.py @@ -47,6 +47,37 @@ def test_mud_screen_flush_clears_buffer(): assert second == "" +def test_mud_screen_suppresses_upper_window_writes(): + """MudScreen discards writes to upper window (status line).""" + screen = MudScreen() + screen.write("before ") + screen.select_window(1) # upper window + screen.write("STATUS LINE") + screen.select_window(0) # back to lower window + screen.write("after") + output = screen.flush() + assert output == "before after" + + +def test_mud_screen_lower_window_is_default(): + """MudScreen starts with lower window active, writes are captured.""" + screen = MudScreen() + screen.write("hello") + assert screen.flush() == "hello" + + +def test_mud_screen_upper_window_multiple_writes(): + """MudScreen discards all writes while upper window is active.""" + screen = MudScreen() + screen.select_window(1) + screen.write("Room Name") + screen.write(" | Score: 0") + screen.select_window(0) + screen.write("You are in a dark room.\n") + output = screen.flush() + assert output == "You are in a dark room.\n" + + def test_mud_input_stream_feed_and_read(): """MudInputStream feed and read_line work with threading.""" stream = MudInputStream()