Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <BeaverBuddies.dll>`
(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
Expand Down Expand Up @@ -127,8 +127,8 @@ When asked to "update the website for the latest release, consistent with the de
`gh release view <tag> -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.
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Version>`, 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 `<Version>`, and `build.ps1` stops before packaging when a built DLL carries another version.

## Website

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -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. -->
<PropertyGroup>
<Version>1.2.0</Version>
<Version>1.2.1</Version>
</PropertyGroup>
</Project>
7 changes: 4 additions & 3 deletions PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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).
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/) <!-- latest -->
**[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/) <!-- latest -->

> **v1.2.0** is the current release, built for Timberborn **1.1.2.4**. One download covers single-player and BeaverBuddies multiplayer. <!-- latest -->
> **v1.2.1** is the current release, built for Timberborn **1.1.2.4**. One download covers single-player and BeaverBuddies multiplayer. <!-- latest -->

<img width="625" height="1112" alt="image" src="https://github.com/user-attachments/assets/862e5c13-33a0-47ed-9515-9e2dffefe3a9" />

Expand All @@ -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**. <!-- latest -->
1. Download **MixedStorage-v1.2.1.zip** above. On the release page, choose that file under **Assets**, not **Source code**. <!-- latest -->
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.
Expand Down Expand Up @@ -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.

Expand Down
9 changes: 9 additions & 0 deletions docs/assets/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@
'<div class="ig-bar-track"><i style="width:' + fill + '%"></i></div></div>';
});
els.cards.innerHTML = shown ? html : '<p class="ig-empty">No goods allocated or stored.</p>';
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 ----
Expand Down Expand Up @@ -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;
Expand Down
15 changes: 8 additions & 7 deletions docs/assets/game-panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
8 changes: 4 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ <h2>Right inside the building's window</h2>
<figcaption>The mix in the world. The split is approximate and banners show one good; the panel has the exact counts.</figcaption>
</figure>
<ul class="ledger" style="margin-top:28px;grid-template-columns:minmax(0,1fr)">
<li><b>Stock at a glance</b><p>Summary cards show each good's stock, limit, share and fill bar, with incoming deliveries and excess.</p></li>
<li><b>Stock at a glance</b><p>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.</p></li>
<li><b>Quick setup</b><p>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.</p></li>
<li><b>Drafts until you Apply</b><p>Edits change nothing until you press Apply. Apply has an orange ring while it would change the building.</p></li>
<li><b>Fits your screen</b><p>The editor is sized to your window and leaves room for the game's Construction site panel.</p></li>
Expand Down Expand Up @@ -223,9 +223,9 @@ <h3>Things to try</h3>

<section class="ig-sec ig-alloc" aria-label="Storage Allocation">
<h3 class="ig-title">Storage Allocation</h3>
<p class="ig-summary" data-summary></p>
<div class="ig-cards ig-cards--pinned" data-cards tabindex="0" role="region" aria-label="Allocated goods"></div>
<div class="ig-scroll" data-scroll tabindex="0" role="region" aria-label="Storage allocation settings, scrollable">
<p class="ig-summary" data-summary></p>
<div class="ig-cards" data-cards></div>
<div class="ig-search">
<label for="ig-search">Search</label>
<input id="ig-search" class="ig-input" type="text" autocomplete="off" spellcheck="false" data-search title="Search the goods allowed in this storage building.">
Expand Down Expand Up @@ -297,7 +297,7 @@ <h2>Up and running in three steps</h2>
<div class="wrap">
<div class="panel note note--info measure">
<h3>What's been played</h3>
<p>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.</p>
<p>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.</p>
<p>Found something odd? <a href="troubleshooting.html">Check the troubleshooting guide</a> or <a href="https://github.com/timbermods/MixedStorage/issues" rel="noopener">open an issue</a>.</p>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packaging/MixedStorage/version-1.1/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "MixedStorage",
"Version": "1.2.0",
"Version": "1.2.1",
"Id": "kyler.mixedstorage",
"MinimumGameVersion": "1.1.2.4",
"Description": "Per-good percentage allocations for warehouses and small, large, industrial and underground piles. Uses each building's allowed goods. Search, set exact percentages, and apply when the total is 100%, or 0% to store nothing.",
Expand Down
Loading