Appearance
Resources
A resource is a named scalar in your game state. Economy stores the definition, not the balance.
ts
type ResourceId = string;
interface ResourceAccessor<T> {
get(state: T): number;
add(state: T, amount: number): void;
}Resource ids
ResourceId is a plain string. Runtime validation rejects empty ids, whitespace and ids that start or end with :.
The recommended convention is namespace:name, for example currency:coins, producer:farm or card:manager:shards.
Resource definitions
ResourceInit<T> is the author-facing declaration. It accepts either an accessor or inline get/add functions.
ts
import { createEconomy, stateKey } from "@idlekitjs/economy";
interface State {
coins: number;
science: number;
}
const economy = createEconomy<State>()
.resource({
id: "currency:coins",
label: "Coins",
accessor: stateKey("coins"),
})
.resource({
id: "currency:science",
label: "Science",
get: (state) => state.science,
add: (state, amount) => {
state.science += amount;
},
integer: true,
});createEconomy().resource(init) registers a resource and returns the same economy for chaining. createEconomy().resource(id) looks up a registered ResourceDef<T> and throws on an unknown id.
Defaults
defineResource normalizes every ResourceInit<T> into a ResourceDef<T>.
| Field | Default |
|---|---|
label | id |
integer | false |
min | 0 |
max | Infinity |
tags | [] |
The economy-wide formatter defaults to String. A resource-level format function overrides it for that resource.
min and max are balance bounds. add and credit clamp into the bounds. Spending uses the spendable balance: current - min.
integer: true validates moved amounts. Economy does not silently round.
State ownership
The game owns the state. Economy reaches the value only through the resource accessor.
ts
const def = economy.resource("currency:coins");
def.accessor.get(state); // same value as economy.get(state, "currency:coins")This keeps resources usable with plain objects, reactive stores, tests and mechanic-owned state slices.