Summary
ScrollHelper.set_target_fps() computes frame_time_target and nothing ever reads it. The global target-FPS setting that 19 plugins carefully wire up does not influence scrolling at all.
Found while sweeping for ZeroDivisionError exposure on the render path (the 1.0 / self.target_fps divisions). The divisions turned out to be properly clamped; the value they produce turned out to be unused.
Evidence
frame_time_target is assigned in exactly two places and read in exactly one — a debug log:
src/common/scroll_helper.py:91 self.frame_time_target = 1.0 / self.target_fps # __init__
src/common/scroll_helper.py:936 self.frame_time_target = 1.0 / self.target_fps # set_target_fps
src/common/scroll_helper.py:937 logger.debug(f"... (frame_time_target: {self.frame_time_target:.4f}s)")
Searched both repos, including getattr-style dynamic access: no other reads. Ten plugins also assign it directly on the older-core fallback path, and none of them read it either.
Scroll pacing comes entirely from scroll_delay:
# scroll_helper.py:249
if time_since_last_step >= self.scroll_delay:
steps = int(time_since_last_step / self.scroll_delay)
max_steps = max(1, int(0.04 / self.scroll_delay))
and sports_scroll.display_scroll_frame() calls update_scroll_position() without sleeping on any target.
Why this matters
src/common/sports_scroll.py:275 states the module's reason for existing:
The reason this module exists upstream: the bundled copies hardcode ~100 FPS via scroll_delay and never consult the global target.
It then calls set_target_fps(target_fps) — which sets a value nothing consumes. The problem the module was written to solve is not solved by the call it makes.
CLAUDE.md in the plugins repo documents this as the mechanism for smooth scrolling:
Global target FPS — read global_config['target_fps'] (fallback scroll_target_fps, default ~100) and push it into the scroll helper: self.scroll_helper.set_target_fps(target_fps)
19 plugins follow that guidance, most reproducing the max(30.0, min(200.0, fps)) clamp by hand for older cores. All of it is inert.
What I did not do
The fix is a pacing change — most plausibly having set_target_fps also derive scroll_delay (1.0 / target_fps), or having the frame pump sleep on frame_time_target. Either alters scroll speed on every scrolling plugin, and could slow content that currently runs at the 0.001s default (1000 FPS cap) rather than speed anything up.
Both rigs have been unreachable all day, so I can't watch a panel to see what that does. Changing scroll pacing blind seemed like the wrong call, particularly given how sensitive refresh-rate behaviour has been on these panels.
Happy to implement whichever direction you want once it can be checked on hardware.
Scope note
vegas_config.target_fps is a different setting and is genuinely used (vegas_mode/coordinator.py, render_pipeline.py). This issue is only about ScrollHelper.target_fps.
Summary
ScrollHelper.set_target_fps()computesframe_time_targetand nothing ever reads it. The global target-FPS setting that 19 plugins carefully wire up does not influence scrolling at all.Found while sweeping for
ZeroDivisionErrorexposure on the render path (the1.0 / self.target_fpsdivisions). The divisions turned out to be properly clamped; the value they produce turned out to be unused.Evidence
frame_time_targetis assigned in exactly two places and read in exactly one — a debug log:Searched both repos, including
getattr-style dynamic access: no other reads. Ten plugins also assign it directly on the older-core fallback path, and none of them read it either.Scroll pacing comes entirely from
scroll_delay:and
sports_scroll.display_scroll_frame()callsupdate_scroll_position()without sleeping on any target.Why this matters
src/common/sports_scroll.py:275states the module's reason for existing:It then calls
set_target_fps(target_fps)— which sets a value nothing consumes. The problem the module was written to solve is not solved by the call it makes.CLAUDE.mdin the plugins repo documents this as the mechanism for smooth scrolling:19 plugins follow that guidance, most reproducing the
max(30.0, min(200.0, fps))clamp by hand for older cores. All of it is inert.What I did not do
The fix is a pacing change — most plausibly having
set_target_fpsalso derivescroll_delay(1.0 / target_fps), or having the frame pump sleep onframe_time_target. Either alters scroll speed on every scrolling plugin, and could slow content that currently runs at the 0.001s default (1000 FPS cap) rather than speed anything up.Both rigs have been unreachable all day, so I can't watch a panel to see what that does. Changing scroll pacing blind seemed like the wrong call, particularly given how sensitive refresh-rate behaviour has been on these panels.
Happy to implement whichever direction you want once it can be checked on hardware.
Scope note
vegas_config.target_fpsis a different setting and is genuinely used (vegas_mode/coordinator.py,render_pipeline.py). This issue is only aboutScrollHelper.target_fps.