From d5842e9d5fe453cfab95da1744a287b015e39c80 Mon Sep 17 00:00:00 2001 From: Kyler Ramsey Date: Sun, 27 Sep 2026 12:43:18 -0700 Subject: [PATCH] v1.2.1: keep the summary and two goods cards in view while scrolling The Storage Allocation panel's summary line and goods cards now sit above the scrolling goods list instead of scrolling away with it. The card list shows two cards at most and scrolls itself when more goods are allocated or stored. The site's panel replica matches. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 6 +++ CLAUDE.md | 6 +-- DEVELOPMENT.md | 2 +- Directory.Build.props | 2 +- PRODUCT.md | 7 ++-- README.md | 10 ++--- docs/assets/demo.js | 9 +++++ docs/assets/game-panel.css | 15 +++---- docs/index.html | 8 ++-- .../MixedStorage/version-1.1/manifest.json | 2 +- source/StorageView.cs | 40 ++++++++++++++++--- 11 files changed, 76 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 208ef67..12c1dfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.2.1 + +The storage panel keeps what's stored in view. Saves and co-op work with v1.2.0; co-op players should still update together. + +- The summary line and the goods cards now stay at the top of the Storage Allocation panel while you scroll the goods list. The cards show two goods at a time; with more goods allocated or stored, scroll the cards themselves. + ## v1.2.0 Two panel improvements. **All co-op players must update together**: earlier versions refuse an Apply that stores nothing. Saves load both ways with v1.1.x. diff --git a/CLAUDE.md b/CLAUDE.md index d9a5131..dea1b63 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ through a PR → merge. - CI (`.github/workflows/tests.yml`, every PR) runs, and you can run locally without the game: `dotnet run --project tests/AllocationTests.csproj -c Release` (prints `PASS: 19,138 assertions…`), - `node tests/test-site.mjs` (76/76), and `powershell -NoProfile -Command ".\tests\check-version.ps1"` (prints `1.2.0`). + `node tests/test-site.mjs` (76/76), and `powershell -NoProfile -Command ".\tests\check-version.ps1"` (prints `1.2.1`). - The full mod build needs the game and DLLs: `.\build.ps1 -HarmonyPath <0Harmony.dll> -BeaverBuddiesPath ` (see `DEVELOPMENT.md`). The version lives only in `Directory.Build.props` plus `packaging/MixedStorage/version-1.1/manifest.json`; a release bump also touches README, CHANGELOG.md and the site's @@ -127,8 +127,8 @@ When asked to "update the website for the latest release, consistent with the de `gh release view -R timbermods/MixedStorage`, README, CHANGELOG.md, `DEVELOPMENT.md`. List every player-facing change. 2. Update every place the site states a changed fact: - - `release.js` fills `data-release="tag"` (fallback text `v1.2.0`), `data-release="asset-name"` (fallback - `MixedStorage-v1.2.0.zip`), `data-release-href="download"|"notes"` (fallback `…/releases/latest` or + - `release.js` fills `data-release="tag"` (fallback text `v1.2.1`), `data-release="asset-name"` (fallback + `MixedStorage-v1.2.1.zip`), `data-release-href="download"|"notes"` (fallback `…/releases/latest` or `…/releases`) and the `data-release-show` pills. The tag and zip-name fallbacks are updated automatically when a release is marked Latest (`.github/workflows/latest-release.yml`); the site test checks that the install guide keeps the zip name it was written with. Pre-releases change nothing. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 5512db8..dda0a48 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -62,7 +62,7 @@ The mod reuses the installed game's styles and assets: `NineSliceVisualElement` - Isolated loading processes with and without BeaverBuddies check eager main-type enumeration, bridge event discovery, delegate installation, repeated initialization, and obsolete-addon rejection. A stub BeaverBuddies with one member missing (`loading-tests/StubBeaverBuddies`) checks that an incompatible build is skipped without stopping startup, that the reason names exactly that member, that a failed bridge is not loaded twice, and that Apply without the bridge only counts as single-player when BeaverBuddies reports no connection. They also check that every prefix that can replace the game's method (every prefix returning `bool`, in every class Harmony's `PatchAll` would patch) carries `[HarmonyPriority(Priority.Last)]`, on the method or on its class. - BeaverBuddies replays the Duplicate settings tool on every player. A loading check walks the IL of the patches that run inside that replay, and of every mod method they call, and fails if any of them reads the panel's message or pending state, the panel or renderer, submits a command, or reads a clock, input or random numbers (`loading-tests/ReplayChecks.cs`). Two control scans check that it finds such state where the mod does use it. -Loading checks run under .NET, not inside Unity/Mono. They do not establish live multiplayer compatibility. Builds pass without compiler warnings; v0.5.8's layout has been visually verified in game, and v1.0.0 through v1.2.0 leave it unchanged apart from v1.2.0's ring around Apply. The v1.0.0 to v1.2.0 Duplicate settings, startup, loading, Supply order, editor status, patch priority, announcement, store-nothing and Apply ring changes have not been exercised in game yet. The mod's startup log line reads its version from the assembly, and both DLLs take theirs from `Directory.Build.props`, so a release bump touches only that file, the manifest, the README and changelog, and the website's Project status note in `docs/index.html`. `tests/check-version.ps1`, which `build.ps1` runs before building and CI runs on every pull request, fails when the manifest's version differs from `Directory.Build.props` or a mod `.csproj` sets its own ``, and `build.ps1` stops before packaging when a built DLL carries another version. +Loading checks run under .NET, not inside Unity/Mono. They do not establish live multiplayer compatibility. Builds pass without compiler warnings; v0.5.8's layout has been visually verified in game, and v1.0.0 through v1.2.1 leave it unchanged apart from v1.2.0's ring around Apply and v1.2.1's pinned summary and cards. The v1.0.0 to v1.2.0 Duplicate settings, startup, loading, Supply order, editor status, patch priority, announcement, store-nothing, Apply ring and pinned-cards changes have not been exercised in game yet. The mod's startup log line reads its version from the assembly, and both DLLs take theirs from `Directory.Build.props`, so a release bump touches only that file, the manifest, the README and changelog, and the website's Project status note in `docs/index.html`. `tests/check-version.ps1`, which `build.ps1` runs before building and CI runs on every pull request, fails when the manifest's version differs from `Directory.Build.props` or a mod `.csproj` sets its own ``, and `build.ps1` stops before packaging when a built DLL carries another version. ## Website diff --git a/Directory.Build.props b/Directory.Build.props index fcf7999..cbd9911 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,6 +3,6 @@ with it (and the startup log line reads it from the assembly). build.ps1 refuses to build when packaging/MixedStorage/version-1.1/manifest.json says otherwise, and to package a DLL built with another. --> - 1.2.0 + 1.2.1 diff --git a/PRODUCT.md b/PRODUCT.md index 917862f..438f256 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -34,12 +34,12 @@ models. One download covers single player and co-op. ## Operating Context -- Current release: **v1.2.0** (a stable Latest release; `release.js` fills the version and zip link). Built for +- Current release: **v1.2.1** (a stable Latest release; `release.js` fills the version and zip link). Built for Timberborn **1.1.2.4**. Requires **Harmony 2.4.1** or newer. Optional co-op through the **BeaverBuddies Stability Fork** (support is bundled; every player needs the same MixedStorage and game version). - Supported: Folktails small/medium/large warehouses and small/large/underground piles; Iron Teeth small/medium/large warehouses and small/large industrial piles. Not tanks or map-editor reserve storage. -- The panel: Storage Allocation in the building's window; summary cards; Search; Allocated goods only; Max; x +- The panel: Storage Allocation in the building's window; summary cards (pinned above the goods list, two at a time); Search; Allocated goods only; Max; x (reset); Clear all; Revert; Copy / Paste allocations; Apply 100% (Apply: store nothing at 0%). Edits are drafts until Apply; Apply gets an orange ring while the draft differs. The game's Copy settings tool copies allocations. - Reporting: GitHub issues with Player.log (`%USERPROFILE%\AppData\LocalLow\Mechanistry\Timberborn`), versions, other @@ -59,7 +59,8 @@ models. One download covers single player and co-op. - Terminology as in game and README: Storage Allocation, Apply 100%, Apply: store nothing, Copy allocations, Paste allocations, Clear all, Revert, Max, Allocated goods only, excess, Accept / Obtain / Supply / Empty. - **Honest status:** the v0.5.8 panel layout and v0.5.7 storage visuals were verified in game; later changes (Copy - settings, error messages, Supply order, store nothing, the Apply ring, and more) haven't been played in game yet. + settings, error messages, Supply order, store nothing, the Apply ring, the pinned cards, + and more) haven't been played in game yet. Say so plainly. Describe the mod as it is now; version history belongs in the changelog. Keep the upgrade facts players need (replace the files with the game closed; allocations are kept; remove the old MixedStorage-BeaverBuddies addon if present). diff --git a/README.md b/README.md index 5e85863..d31c8ef 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ Give each good a percentage of the building's capacity. At **50% carrots** and **50% gears**, a 1,200-capacity warehouse holds 600 of each. Percentages reserve space; they don't create goods or fill the building. -**[Download MixedStorage v1.2.0](https://github.com/timbermods/MixedStorage/releases/download/v1.2.0/MixedStorage-v1.2.0.zip)** · [Release notes](https://github.com/timbermods/MixedStorage/releases/tag/v1.2.0) · [Report a problem](https://github.com/timbermods/MixedStorage/issues) · [Website](https://timbermods.github.io/MixedStorage/) +**[Download MixedStorage v1.2.1](https://github.com/timbermods/MixedStorage/releases/download/v1.2.1/MixedStorage-v1.2.1.zip)** · [Release notes](https://github.com/timbermods/MixedStorage/releases/tag/v1.2.1) · [Report a problem](https://github.com/timbermods/MixedStorage/issues) · [Website](https://timbermods.github.io/MixedStorage/) -> **v1.2.0** is the current release, built for Timberborn **1.1.2.4**. One download covers single-player and BeaverBuddies multiplayer. +> **v1.2.1** is the current release, built for Timberborn **1.1.2.4**. One download covers single-player and BeaverBuddies multiplayer. image @@ -15,13 +15,13 @@ Give each good a percentage of the building's capacity. At **50% carrots** and * ## What you can do - **Mix goods:** give a percentage to any good the building normally accepts. -- **See your stock at a glance:** summary cards show each good's stock, limit, share and fill bar. +- **See your stock at a glance:** summary cards show each good's stock, limit, share and fill bar, and stay in view while you scroll the goods list. - **Set up quickly:** search the list, give one good everything with **Max**, or copy a split to another building. - **See the mix in the world:** the building shows its goods with the game's own models. ## Install -1. Download **MixedStorage-v1.2.0.zip** above. On the release page, choose that file under **Assets**, not **Source code**. +1. Download **MixedStorage-v1.2.1.zip** above. On the release page, choose that file under **Assets**, not **Source code**. 2. Close Timberborn. Extract the ZIP's **MixedStorage** folder into `Documents\Timberborn\Mods`. 3. Check that `Documents\Timberborn\Mods\MixedStorage\version-1.1\manifest.json` exists, with no extra folder in between. 4. Install **Harmony** 2.4.1 or newer from the [Steam Workshop](https://steamcommunity.com/sharedfiles/filedetails/?id=3284904751) if you don't have it. @@ -111,7 +111,7 @@ Close Timberborn, then disable MixedStorage or delete its folder. In saves that ## Compatibility and testing -The panel's layout and the storage visuals have been checked in game, and players have reported using the mod. The newer behavior passes automated checks but hasn't been played yet, alone or in co-op. That includes the game's Copy settings tool, storing nothing, the orange ring on Apply, Supply mode, loading damaged saves and the panel's messages. +The panel's layout and the storage visuals have been checked in game, and players have reported using the mod. The newer behavior passes automated checks but hasn't been played yet, alone or in co-op. That includes the game's Copy settings tool, storing nothing, the orange ring on Apply, the cards staying in view, Supply mode, loading damaged saves and the panel's messages. See the [changelog](CHANGELOG.md) for version history and the [developer notes](DEVELOPMENT.md) for building and how the mod works. diff --git a/docs/assets/demo.js b/docs/assets/demo.js index db1d21e..07e9aad 100644 --- a/docs/assets/demo.js +++ b/docs/assets/demo.js @@ -178,6 +178,13 @@ '
'; }); els.cards.innerHTML = shown ? html : '

No goods allocated or stored.

'; + fitCards(); + } + // As in the mod: the cards stay above the scrolling list, and show two at most; more scroll inside. + function fitCards() { + var cards = els.cards.children, height = 0; + for (var i = 0; i < cards.length && i < 2; i++) height += cards[i].offsetHeight + (parseFloat(getComputedStyle(cards[i]).marginBottom) || 0); + els.cards.style.maxHeight = cards.length > 2 ? height + 'px' : ''; } // ---- actions ---- @@ -210,6 +217,8 @@ els.scroll.scrollTop = 0; } + window.addEventListener('resize', fitCards); + els.rows.addEventListener('click', function (e) { var btn = e.target.closest('button'); if (!btn) return; diff --git a/docs/assets/game-panel.css b/docs/assets/game-panel.css index e68ebd2..1eb38bd 100644 --- a/docs/assets/game-panel.css +++ b/docs/assets/game-panel.css @@ -72,13 +72,14 @@ /* the mod's panel */ .ig-alloc { padding: 10px 4px 9px 11px; } .ig-title { margin: 0 0 3px; font-size: 16px; font-weight: 700; text-transform: uppercase; color: #fff; letter-spacing: 0; } -.ig-scroll { max-height: 380px; overflow-y: auto; overflow-x: hidden; padding-right: 4px; scrollbar-gutter: stable; } -.ig-scroll:focus-visible { outline: 3px solid var(--ig-orange); outline-offset: 2px; } -.ig-scroll::-webkit-scrollbar { width: 16px; } -.ig-scroll::-webkit-scrollbar-track { background: linear-gradient(90deg, transparent 4px, #214545 4px, #214545 12px, transparent 12px); border-radius: 6px; } -.ig-scroll::-webkit-scrollbar-thumb { background: #47f7e8; border: 2px solid #f5e8a0; border-radius: 4px; min-height: 44px; box-shadow: inset 0 0 0 1px #2b6a63; } -.ig-scroll::-webkit-scrollbar-thumb:hover { background: #7bfff2; } -@-moz-document url-prefix() { .ig-scroll { scrollbar-color: #47f7e8 #214545; scrollbar-width: auto; } } +.ig-scroll { max-height: 300px; overflow-y: auto; overflow-x: hidden; padding-right: 4px; scrollbar-gutter: stable; } +.ig-scroll:focus-visible, .ig-cards--pinned:focus-visible { outline: 3px solid var(--ig-orange); outline-offset: 2px; } +.ig-cards--pinned { overflow-y: auto; overflow-x: hidden; padding-right: 4px; } +.ig-scroll::-webkit-scrollbar, .ig-cards--pinned::-webkit-scrollbar { width: 16px; } +.ig-scroll::-webkit-scrollbar-track, .ig-cards--pinned::-webkit-scrollbar-track { background: linear-gradient(90deg, transparent 4px, #214545 4px, #214545 12px, transparent 12px); border-radius: 6px; } +.ig-scroll::-webkit-scrollbar-thumb, .ig-cards--pinned::-webkit-scrollbar-thumb { background: #47f7e8; border: 2px solid #f5e8a0; border-radius: 4px; min-height: 44px; box-shadow: inset 0 0 0 1px #2b6a63; } +.ig-scroll::-webkit-scrollbar-thumb:hover, .ig-cards--pinned::-webkit-scrollbar-thumb:hover { background: #7bfff2; } +@-moz-document url-prefix() { .ig-scroll, .ig-cards--pinned { scrollbar-color: #47f7e8 #214545; scrollbar-width: auto; } } .ig-summary { font-size: 16px; font-weight: 700; color: #fff; } /* summary cards */ diff --git a/docs/index.html b/docs/index.html index 4299c41..6bd0c03 100644 --- a/docs/index.html +++ b/docs/index.html @@ -151,7 +151,7 @@

Right inside the building's window

The mix in the world. The split is approximate and banners show one good; the panel has the exact counts.
    -
  • Stock at a glance

    Summary cards show each good's stock, limit, share and fill bar, with incoming deliveries and excess.

  • +
  • Stock at a glance

    Summary cards show each good's stock, limit, share and fill bar, with incoming deliveries and excess. They stay in view while you scroll the goods list.

  • Quick setup

    Search the list, show only allocated goods, give one good everything with Max, or copy a split to another building. The game's Copy settings tool copies it too.

  • Drafts until you Apply

    Edits change nothing until you press Apply. Apply has an orange ring while it would change the building.

  • Fits your screen

    The editor is sized to your window and leaves room for the game's Construction site panel.

  • @@ -223,9 +223,9 @@

    Things to try

    Storage Allocation

    +

    +
    -

    -