Skip to content

Fit the signal grid to the screen instead of running off it - #4

Merged
danbopes merged 1 commit into
masterfrom
signal-grid-fit-to-screen
Aug 1, 2026
Merged

danbopes merged 1 commit into
masterfrom
signal-grid-fit-to-screen

Conversation

@danbopes

@danbopes danbopes commented Aug 1, 2026 •

Copy link
Copy Markdown
Owner

Addresses the report that the signal window does not fit on screen in pY.

The problem

The grid was a fixed 8-column table with no scroll pane and no height cap, so the window grew one row per 8 signals without bound. Measured on a graphical 2.1.7 host at 3600x2025 / 1.5 UI scale:

signals before after
8 8 cols, 1 row 8 cols, 1 row (unchanged)
60 8 cols, 8 rows 10 cols, 6 rows
400 8 cols, 50 rows 24 cols, 17 rows
800 8 cols, 100 rows, pinned to y=0 24 cols, 20 visible + scroll
1502 8 cols, 188 rows 24 cols, 20 visible + scroll

At 800 signals the old window sat at y=0 and ran off the bottom with roughly a third of the rows reachable and no way to get at the rest.

Approach

Widening alone does not solve it. 800 signals still needs 24 columns to fit at 1080p, and a window that wide is absurd for a reader showing three signals. So the grid sizes itself, with no settings to configure:

  • Table lives in a scroll-pane capped at 60% of screen height, rounded down to whole rows so none is cut in half.
  • Column count derives from the signal count, clamped to what the screen allows. Small readers stay as compact as today; large ones widen to the cap and then scroll.

Rode along

Three things that only bite at this scale:

  • update_signal_display cleared and refilled the whole table each update, which would reset scroll position twice a second and rebuild hundreds of elements. Buttons are now updated in place, surplus destroyed.
  • Section 2 is rebuilt from a hash table each update, so order drifted between refreshes. Entries now sort into prototype order, keyed by type/name/quality so the order is total and identical on every client.
  • The per-button prototype lookup had no nil guard, so opening a reader whose stored output named an item from a removed mod raised.

Also fixed force_auto_center running before the grid was populated, which centred the empty window and left it hanging off the bottom as rows arrived.

Net diff is three files: gui.lua, gui-styles.lua (drops the dead cybersyn_content_reader_signal_display style that hardcoded the 280x300 geometry this replaces), and changelog.txt.

Verification

Suite is 9/9 (./factorio-test.py cybersyn-content-reader). Screenshots taken against a live graphical host at each of the sizes in the table, including scrolled-to-bottom at 800.

Not exercised end-to-end: scroll position surviving a live Update_Combinator cycle. That needs a tracked reader, whose section 2 gets overwritten from real Cybersyn state each tick, which would wipe the synthetic signals. The change is structural (no more clear()), but I did not watch it happen in game.

Versioning

Stays on the pending 1.1.1. Only 1.1.0 is tagged on the remote, so the Version: 1.1.1 / Date: ???? block is fmtk's post-release stub from shipping 1.1.0 and was never published; these entries belong in it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01A47dkZVVahTZsepP8LnbLM

A reader aggregating a whole network produced a fixed 8-column table with no
scroll pane and no height cap, so the window grew one row per 8 signals until it
ran off the bottom of the display. On a pY-sized network that is 100 rows, of
which only about a third are reachable at any window position.

Widening alone does not fix it: 800 signals still needs 24 columns to fit at
1080p, and a fixed width that wide is absurd for a reader showing three signals.
So the grid sizes itself, with no knobs:

- The table lives in a scroll-pane capped at 60% of screen height, rounded down
  to whole rows so no row is cut in half.
- Column count is derived from the signal count, clamped to what the screen
  allows. Small readers stay exactly as compact as before; large ones widen to
  the cap and then scroll.

Three problems that only bite at that scale come along with it:

- update_signal_display cleared and refilled the table on every update, which
  would reset the scroll position twice a second and rebuild hundreds of
  elements. Buttons are now updated in place and only the surplus destroyed.
- Section 2 is rebuilt from a hash table each update, so signal order drifted
  between refreshes. Entries are sorted into prototype order, keyed by type,
  name and quality so the order is total and identical on every client.
- The prototype lookup behind each button had no nil guard, so opening a reader
  whose stored output named an item from a removed mod raised.

force_auto_center now runs after the grid is populated; centring the empty
window first left it hanging off the bottom as the rows arrived.

Also drops the dead cybersyn_content_reader_signal_display style, which
hardcoded the 280x300 geometry this replaces, along with the stale commented-out
scaffolding and a duplicate button.number assignment.

Verified against a graphical 2.1.7 host at 3600x2025 / 1.5 UI scale: 8 signals
render 8x1 as before, 60 render 10x6, 800 render 24 columns capped at 20 visible
rows with all of them reachable by scrolling, and 1502 behave the same. Suite is
9/9.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A47dkZVVahTZsepP8LnbLM
@danbopes
danbopes force-pushed the signal-grid-fit-to-screen branch from 9230988 to 43d1635 Compare August 1, 2026 15:55
@danbopes
danbopes merged commit 00d77be into master Aug 1, 2026
1 check passed
@danbopes
danbopes deleted the signal-grid-fit-to-screen branch August 1, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant