Skip to content

Authoring Items Consumable

EmoTracker Community edited this page Apr 8, 2026 · 3 revisions

Authoring Items — Consumable

A consumable is a counter — an icon paired with a number. Used for anything the player collects multiples of: bottles, bombs, arrows, small keys, hearts, required-crystal trackers, and so on.

See Authoring Items for the general items file format and base fields. This page only covers fields specific to the consumable type.

JSON schema

Parsed in EmoTracker.Data/Items/ConsumableItem.cs. Matches the consumable branch in items.json.

Field Type Required Default Description
type "consumable" yes Literal string.
img string yes Path (relative to pack root) to the "full" (non-empty) image.
img_mods string no Comma-separated image filter spec applied to img.
disabled_img string no derived from img Image used when the count is at the minimum. If omitted, EmoTracker derives one by applying disabled_img_mods (or the pack-level default filter) to img.
disabled_img_mods string no inherited Image filter spec applied to the empty-state image.
codes string yes Comma-separated codes this consumable provides.
initial_quantity integer no 0 Starting count.
min_quantity integer no 0 Lowest count the user can decrement to.
max_quantity integer no int.MaxValue Highest count the user can increment to.
increment integer no 1 How much each click adjusts the count. Useful for things you collect in groups (e.g. 5 bombs per bomb bag).
swap_actions boolean no false If true, left click decrements and right click increments (instead of the default). Useful for "countdown" items like crystals required.
display_as_fraction_of_max boolean no false If true, the badge text shows current/max instead of just current. Requires max_quantity to be set to something finite.

Plus the standard base fields from Authoring Items → Fields every item shares.

Mouse behavior

Button swap_actions: false swap_actions: true
Left click Increment count by increment (clamped to max_quantity) Decrement count by increment (clamped to min_quantity)
Right click Decrement count by increment (clamped to min_quantity) Increment count by increment (clamped to max_quantity)

See Item Types And Mouse Controls → Consumable for the user-facing explanation.

How logic sees consumables

A consumable provides its codes with a count, not a simple yes/no. Logic can query the count in two ways:

  • has("bomb") returns true if the current count is greater than zero.
  • count("bomb") returns the actual numeric value, so logic can compare count("bomb") >= 5.

The count the runtime exposes is the available count (AcquiredCount - ConsumedCount). Some advanced packs mark items as consumed when they get used up — for the vast majority of packs you can ignore the consumed concept and just think in terms of the current quantity.

Examples

Heart pieces — classic 0-to-N counter

{
  "name": "Heart Piece",
  "type": "consumable",
  "img": "images/items/heartpiece.png",
  "codes": "heartpiece",
  "max_quantity": 24,
  "initial_quantity": 0
}

Dungeon small keys — capped at the dungeon's key count

Each small key slot in ALttPR is a separate consumable with its own max_quantity:

{
  "name": "Palace of Darkness Small Key",
  "type": "consumable",
  "img": "images/items/smallkey_pod.png",
  "codes": "smallkey0",
  "max_quantity": 6
}

Bomb bags — increment greater than 1

If the player gets bombs in packs of 5, set increment: 5 so a single click adds or removes a whole bag:

{
  "name": "Bomb Bag",
  "type": "consumable",
  "img": "images/items/bombs.png",
  "codes": "bomb",
  "max_quantity": 50,
  "increment": 5,
  "display_as_fraction_of_max": true
}

Countdown items — swap_actions + non-zero initial

The GT / Ganon Required Crystals trackers in ALttPR start at 7 and count down as the player confirms how many crystals are required:

{
  "name": "GT Required Crystals",
  "type": "consumable",
  "img": "images/items/crystal.png",
  "codes": "gt_crystals",
  "initial_quantity": 7,
  "min_quantity": 0,
  "max_quantity": 7,
  "swap_actions": true
}

With swap_actions: true, left-clicking decrements (the natural "I confirmed one fewer is required" gesture) and right-clicking increments.

Tips and pitfalls

  • Always set max_quantity. The default of int.MaxValue means the counter grows forever — almost never what you want.
  • display_as_fraction_of_max needs a bounded max. Without one, the denominator makes no sense.
  • Prefer consumables over progressive for anything numeric. Consumables render the number for you and integrate cleanly with autotracker scripts (which typically write a raw quantity).
  • Consider image variants for visual feedback. A disabled_img pointing at a greyed-out version gives clear at-a-glance feedback when the count hits zero.
  • Autotracker scripts can set the count directly via the Lua AcquiredCount accessor on the item — don't feel obligated to simulate clicks.

See also

Clone this wiki locally