Appearance
Containers
containers is a finite-capacity holder for multiple content types. It owns capacity math only: fit checks, fills, partial fills and drains.
ts
import { containers, type ContainersData } from "@idlekitjs/mechanics/containers";Mental model
A container has a finite capacity. Contents are stored by content id:
ts
type ContainerContents = Record<string, number>;
type ContainersData = Record<string, ContainerContents>;Amount and occupied volume can differ. By default, one unit uses one capacity unit. A container can provide volumeOf(contentId, state) to make some content larger or smaller.
used = sum(amount * volumeOf(contentId))
Minimal example
ts
import { containers, type ContainersData } from "@idlekitjs/mechanics/containers";
interface State {
storage: ContainersData;
bonusCapacity: number;
}
const bins = containers<State>({
definitions: [
{ id: "scrap-bin", capacity: 10 },
{
id: "vault",
capacity: (state) => 6 + state.bonusCapacity,
volumeOf: (contentId) => (contentId === "gem" ? 2 : 1),
},
],
getData: (state) => state.storage,
setData: (state, storage) => {
state.storage = storage;
},
});
engine.use(bins);
bins.fill(state, "scrap-bin", "scrap", 3);
bins.used(state, "scrap-bin"); // 3
bins.free(state, "scrap-bin"); // 7API
ts
bins.capacity(state, "scrap-bin");
bins.used(state, "scrap-bin");
bins.free(state, "scrap-bin");
bins.contents(state, "scrap-bin");
bins.canFit(state, "scrap-bin", "scrap", 2);
bins.fill(state, "scrap-bin", "scrap", 2);
bins.fillUpTo(state, "scrap-bin", "scrap", 20);
bins.drain(state, "scrap-bin");
bins.drain(state, "scrap-bin", { contentId: "scrap" });
bins.drain(state, "scrap-bin", { contentId: "scrap", amount: 2 });| Method | Behavior |
|---|---|
capacity | Current capacity. Dynamic capacities are evaluated from state. |
used | Occupied capacity. Unknown containers report 0. |
free | capacity - used. Can be negative if dynamic capacity shrank. |
contents | Snapshot of current contents. Unknown containers report {}. |
canFit | Whether an amount fits now. Amount defaults to 1. |
fill | All-or-nothing fill. Returns false without mutation when it does not fit. |
fillUpTo | Adds what fits up to the requested amount and returns the accepted amount. |
drain | Removes everything, one content type or up to an amount. |
drain returns { removed, remaining }.
Runtime behavior
Definition mistakes throw at wiring time: duplicate container ids and invalid static capacities are bugs.
Unknown container ids are safe at runtime:
- reads report empty or
0; fillreturnsfalse;fillUpToreturns0;drainremoves nothing.
Bad fill amounts (0, negative, non-finite) fail without mutation. A dynamic capacity or volumeOf returning an invalid number throws at call time.
Economy adapter
The optional bridge lives at @idlekitjs/mechanics/containers/economy.
ts
import {
containerContentResources,
containerFreeSpaceResource,
containerHasSpace,
} from "@idlekitjs/mechanics/containers/economy";containerHasSpace(containers, containerId, contentId, amount?) is the natural requirement for deposit or collect transactions.
containerContentResources exposes stored content amounts as Economy resources. Credits go through fill, so transactions should gate capacity with containerHasSpace.
containerFreeSpaceResource exposes remaining capacity as a read-only resource.