File Details
Sophisticated Tab 0.5.1 (Forge 1.20.1)
- R
- May 15, 2026
- 62.52 KB
- 76
- 1.20.1
- Forge
File Name
sophisticatedtab-0.5.1.jar
Supported Versions
- 1.20.1
Curse Maven Snippet
[1.20.1-0.5.1] - 2026-05-14
Fixed
- Settings panel and right-click context menu no longer leak the parent inventory through their backgrounds. The v0.5.0 implementations of BackpackSettingsScreen.java and BackpackTabContextMenu.java rendered the parent screen first (correct, intentional — we want the parent dimmed behind us) and then drew the panel via
GuiGraphics.fill(...)at the pose's default Z=0. BecauseItemRenderer.renderGuiItemin 1.20.1 translates Z forward (slot quad +100, item model +50), every item the parent rendered lived at Z ≈ 100–150 and won the depth test against our Z=0 panel fragments. Result: backpack tabs, inventory slots, hotbar items, and any HUD-adjacent widgets (e.g. JEI's search box) stayed crisply visible inside the panel rectangle while the panel outline survived only in the gaps between items. Fix is topose().pushPose()+translate(0, 0, 400)before drawing the dim, panel BG, widgets, and list content, thenpopPose()once they're all in. Z=400 also matches vanillaScreen.renderTooltipInternal's tooltip Z so our content can never sit under stale tooltip residue from the parent.
[1.20.1-0.5.0] - 2026-05-14
Added — User-configurable tab order, hiding, and settings
- Drag-and-drop tab ordering. Left-click-hold and drag a backpack tab horizontally. The dragged backpack renders as a faded ghost at the cursor and a vertical drop indicator marks the target slot. Release commits the reorder; release without horizontal movement is treated as a normal click and opens the backpack. Threshold: 4 px / 350 ms (constants in TabInteractionHandler.java).
- Right-click context menu on any backpack tab. Four entries:
Open Backpack,Move Left,Move Right,Hide This Backpack. Move entries grey out at the row boundaries; hide greys out for UUID-less backpacks (see Design notes). Menu position auto-clamps when the anchor tab is at the right edge of the row. - Hide individual backpacks so they vanish from the LT row. Hidden backpacks remain in the inventory and are still openable via SB's default
Bkeybind; only the tab is suppressed. - Settings screen (
BackpackSettingsScreen) listing every currently carried backpack plus every saved-but-not-carried UUID. Click a carried row to toggle visibility; the screen is the escape hatch that prevents hiding every tab from trapping the user. Footer buttons:Reset Order,Reset Hidden(both two-step confirm),Clean Unused(one-shot prune of stale UUIDs),Done. - Gear tab on the LT row (priority 100) opens the settings screen. Reuses backpack_tab.png chrome and overlays a
Items.COMPARATORglyph so the iconography stays in line with the rest of the row. Open Tab Settingskeybind (default unbound — assign viaOptions > Controls > Sophisticated Tab). Opens the settings screen during gameplay without needing the inventory.- Per-profile client preferences persisted to
config/sophisticatedtab/tab_preferences.json. Profile key issingleplayer:<level>for both non-LAN and LAN-hosted single-player;server:<ip>for multiplayer connections. Schema is v1, includesorderedBackpacksandhiddenBackpacksper profile. Atomic writes via temp+rename; corrupt files are renamed totab_preferences.json.broken.<ISO-timestamp>on the next launch rather than overwritten in place.
Changed
- BackpackTab.java now resolves its descriptor through BackpackTabResolver.java instead of calling
SophisticatedBackpacksLocator.findAllBackpacks(player)directly. The resolver applies the user's hide-filter and order-sort once and produces the canonical visible list thatBackpackTab(i)indexes into. - BackpackDescriptor.java gains a
uuid()accessor delegating towrapper.getContentsUuid(). Centralizes identity reads so the resolver, preferences model, and active-tab highlight no longer each re-derive it. - SophisticatedBackpacksSizing.java now sizes against the first visible backpack from the resolver instead of the first discovered. Matches what the user sees: the leftmost tab is the screen-sizing anchor even after reordering.
- LegendaryTabsCompat.java exposes the registered
BackpackTabinstances viabackpackTabs()so TabInteractionHandler.java can identify whichTabButtonon the active screen represents which logical index.
Design notes for future contributors
- Why UUID, not slot/tier/name, as the identity anchor? Slot breaks on inventory rearrange. Tier breaks on multiple backpacks of the same tier (the common heavy-player case). Name breaks on rename and collides on identical names.
IStorageWrapper.getContentsUuid()is stable across all three and was already the anchor for v0.3.0's active-tab highlight — v0.5.0 just extends it to ordering and hiding. - Why no item NBT mutation for hide state? Hiding is a local UI preference. Writing it to item NBT would: (a) travel with the backpack if traded, (b) require a server packet, (c) break shared worlds where multiple players see different "carrying" sets. Storing only in the client JSON keeps the contract clean.
- Why no dynamic LegendaryTabs tab re-registration?
TabsMenu.registeris a one-shot atFMLClientSetupEvent. The static-pool-of-eightBackpackTabinstances each resolve their descriptor at render/click time, so the perceived reorder happens entirely inside the resolver — LT priorities20..27never mutate. - UUID-less backpacks (rare; happens on freshly crafted stacks before SB writes the contents UUID) render normally but are excluded from drag-ordering and from
hidepersistence. The context menu greys those entries out, and the settings screen marks them with a*and a tooltip explaining the limitation. If the UUID is assigned later (e.g., on first open), the backpack rejoins the configurable pool automatically. - Right-click capture vs. LT's
Button.onPress. LT'sTabButtonextendsButtonand treats all mouse buttons identically —onPressfires for left, right, and middle clicks the same way. To distinguish right-click without forking LT, TabInteractionHandler.java subscribes toScreenEvent.MouseButtonPressed.PreatEventPriority.HIGHand cancels the event before LT's widget dispatch runs. Left-clicks on our tabs are also captured so we can decide click-vs-drag onMouseButtonReleased.Pre. - TabButton.tabBase field access. LegendaryTabs 1.20.1 exposes the field as
public TabBase tabBase. The hit-test reads it directly; if a future LT release flips it to private, the read is wrapped in try/catch and degrades to a logged warning rather than crashing. - Drag visual via
ScreenEvent.Render.Post. We don't move the liveTabButtonwidgets — they stay rendered at their priority-determined positions. The drag is purely a top-level overlay: faded ghost ItemStack at the cursor plus a 2 px white drop indicator between the nearest tab boundaries. - Preferences scope. Per-world for singleplayer (including LAN-hosted, which uses the same
singleplayer:<level>key as non-LAN) and per-server for multiplayer. Cross-instance share isn't supported — each launcher profile has its ownconfig/sophisticatedtab/.