Skip to content

Economy adapters

Economy adapters are official bridges between @idlekitjs/economy and implemented mechanics.

They are optional and subpath-only:

txt
@idlekitjs/mechanics/producers/economy
@idlekitjs/mechanics/collections/economy
@idlekitjs/mechanics/containers/economy
@idlekitjs/mechanics/crafting/economy
@idlekitjs/mechanics/pickups/economy
@idlekitjs/mechanics/projects/economy
@idlekitjs/mechanics/boosts/economy

They are not exported by the @idlekitjs/mechanics barrel and they do not live under @idlekitjs/economy/adapters.

Boundary

Economy is domain-free: it knows resources, amounts, requirements, transactions, formatting and cost curves. It does not know producer columns, card entries, container contents, pickup items, recipe bags, projects or boost timers.

Each adapter lives beside the mechanic whose state shape it adapts. Core mechanic modules remain usable without Economy.

Producers

ts
import {
  economyPurchase,
  producerOutput,
  producerPurchase,
  producerResourceId,
  producerResources,
} from "@idlekitjs/mechanics/producers/economy";
ExportRole
producerResourceIdproducer:<id> id convention.
producerResourcesDeclare one resource per producer tier, backed by total[index].
producerOutputBridge an Economy resource into the producers resource seam.
economyPurchaseImplement the scalar producers purchase seam through Economy.
producerPurchaseBuild a composite producer purchase transaction from a CostCurve.

Use economyPurchase for single-scalar tier purchases. Use producerPurchase when a producer purchase has multi-resource costs or extra requirements.

ts
const purchase = economyPurchase(economy, (index) =>
  index === 0 ? "currency:coins" : producerResourceId(PRODUCERS[index - 1].id),
);

producerPurchase grants through producers.grant(index, state, quantity, { owned: true }), so the producer purchase count advances after the transaction has paid.

Collections

ts
import {
  cardLevelAtLeast,
  cardLevelBelow,
  cardLevelResourceId,
  cardResources,
  cardShardResourceId,
  hasCardShards,
} from "@idlekitjs/mechanics/collections/economy";
ExportRole
cardShardResourceIdcard:<id>:shards.
cardLevelResourceIdcard:<id>:level.
cardResourcesDeclare writable shard and read-only level resources.
cardLevelAtLeastRequirement over the read-only level.
cardLevelBelowRequirement for "not maxed" gates.
hasCardShardsNon-consuming shard requirement.

cardResources declares two resources per card. Shards are writable integer resources. Levels are read-only integer resources. Collection upgrades remain owned by the collections mechanic or by explicit game code in a transaction apply.

Containers

ts
import {
  containerContentResources,
  containerFreeSpaceResource,
  containerHasSpace,
} from "@idlekitjs/mechanics/containers/economy";
ExportRole
containerHasSpaceRequirement that an amount of content fits now.
containerContentResourcesExpose container content amounts as writable resources.
containerFreeSpaceResourceExpose free capacity as a read-only resource.

Containers stay the source of truth for capacity and contents. Economy can observe and trade the same numbers.

Gate deposits with containerHasSpace before crediting a content resource. containerContentResources credits go through the all-or-nothing fill operation.

ts
import { collectPickup } from "@idlekitjs/mechanics/pickups/economy";

const collectScrap = collectPickup(pickupsExt, {
  itemId: "scrap#1",
  requirements: [containerHasSpace(bin, "scrap-bin", "scrap", 1)],
  apply: (state) => {
    bin.fill(state, "scrap-bin", "scrap", 1);
  },
});

Crafting

ts
import {
  amountsToBag,
  bagToAmounts,
  craftingResources,
  recipeCost,
  recipeReward,
} from "@idlekitjs/mechanics/crafting/economy";
ExportRole
craftingResourcesDeclare ResourceBag entries as Economy resources.
bagToAmountsConvert a ResourceBag to amount lines.
amountsToBagConvert amount lines back to a ResourceBag.
recipeCostRecipe inputs as Cost.
recipeRewardRecipe outputs as Reward.

Crafting keeps the job lifecycle: start consumes inputs, cancel refunds or discards inputs, and update credits completed outputs. The adapter exposes the same stock for Economy formatting and transactions.

ts
const economy = createEconomy<State>().resources(
  craftingResources(["ore", "coal", "iron"], {
    getResources: (state) => state.resources,
    setResources: (state, resources) => {
      state.resources = resources;
    },
  }),
);

Pickups

ts
import { collectPickup, pickupAvailable } from "@idlekitjs/mechanics/pickups/economy";
ExportRole
pickupAvailableRequirement that the item exists and is ready.
collectPickupTransaction for a pickup collect action.

Pickups spawn temporary items. Rewards are credited only when a collect transaction succeeds.

ts
const result = economy.execute(
  state,
  collectPickup(pickupsExt, {
    itemId: "coin#4",
    reward: [["currency:coins", 25]],
  }),
);

Extra requirements can gate collection, for example requiring container space before taking the pickup.

Projects

ts
import { projectFromTransaction } from "@idlekitjs/mechanics/projects/economy";

projectFromTransaction(economy, transaction, options) wraps an Economy transaction as a Project<T>.

Project fieldMapping
idtransaction.id
affordableeconomy.canExecute(state, transaction)
effecteconomy.execute(state, transaction)
costFormatted transaction cost unless overridden
triggeroptions.trigger or always visible
repeatableoptions.repeatable

Projects keep completed, repeatable and trigger behavior. Economy supplies the action's affordability, execution and cost formatting.

Boosts

ts
import { activateBoost, boostTokenResourceId } from "@idlekitjs/mechanics/boosts/economy";
ExportRole
boostTokenResourceIdboost-token:<id> token convention.
activateBoostTransaction that spends a token and calls boosts.grant.

The usual pattern is:

  1. Declare a token resource in your game state.
  2. Credit the token as a reward.
  3. Execute activateBoost to spend the token.
  4. Let boosts own timer expiry, stacking and modifier publication.
ts
const result = economy.execute(
  state,
  activateBoost(boostsExt, { boostId: "double-production" }),
);