Summary
The Viser viewer's Rewards bar panel silently displays only the first 20 reward terms. Environments with more than 20 active reward terms have their remaining terms hidden with no warning. The underlying RewardBarPanel already exposes a max_terms parameter, but ViserTermOverlays.setup_tabs does not forward it, so there is no way to raise the limit short of editing the library.
Where
src/mjlab/viewer/viser/reward_bar_panel.py
- L24:
max_terms: int = 20
- L37:
self._term_names = term_names[:max_terms] ← silent truncation
src/mjlab/viewer/viser/overlays.py
- L64:
RewardBarPanel(self.server, term_names, update_dt=self.frame_time) — max_terms is never passed, so it always defaults to 20.
Confirmed present on main and in the released mjlab==1.4.0.
Impact
- Silent data loss. With >20 reward terms, the panel quietly hides the overflow (those defined last in the reward dict). There is no log/warning, so it looks like a complete list.
- Inconsistent with the plot tab.
ViserTermPlotter (the Reward line-plot tab) has no such cap and shows all terms, so the same run shows different term sets in two adjacent tabs — making the truncation easy to miss.
- Misleading during reward debugging. In our wheel-legged balancing task (24 reward terms), the single largest-magnitude penalty term happened to fall past index 20, so it never appeared in the bar panel — exactly the term we most needed to see while diagnosing a policy issue.
Repro
- Define an env with >20 active reward terms.
- Run
mjlab play in the Viser viewer, open the Rewards tab.
- Bar panel shows only the first 20; terms 21+ are absent. The Reward plot tab shows all of them.
Suggested fix
Plumb max_terms through ViserTermOverlays.setup_tabs (and optionally surface it on the viewer config), defaulting to the current 20 to preserve behavior. At minimum, emit a one-time warning when terms are truncated so the loss isn't silent. Happy to send a PR if that's welcome.
Summary
The Viser viewer's Rewards bar panel silently displays only the first 20 reward terms. Environments with more than 20 active reward terms have their remaining terms hidden with no warning. The underlying
RewardBarPanelalready exposes amax_termsparameter, butViserTermOverlays.setup_tabsdoes not forward it, so there is no way to raise the limit short of editing the library.Where
src/mjlab/viewer/viser/reward_bar_panel.pymax_terms: int = 20self._term_names = term_names[:max_terms]← silent truncationsrc/mjlab/viewer/viser/overlays.pyRewardBarPanel(self.server, term_names, update_dt=self.frame_time)—max_termsis never passed, so it always defaults to 20.Confirmed present on
mainand in the releasedmjlab==1.4.0.Impact
ViserTermPlotter(the Reward line-plot tab) has no such cap and shows all terms, so the same run shows different term sets in two adjacent tabs — making the truncation easy to miss.Repro
mjlabplay in the Viser viewer, open the Rewards tab.Suggested fix
Plumb
max_termsthroughViserTermOverlays.setup_tabs(and optionally surface it on the viewer config), defaulting to the current 20 to preserve behavior. At minimum, emit a one-time warning when terms are truncated so the loss isn't silent. Happy to send a PR if that's welcome.