Skip to content

Authoring Items Progressive Toggle

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

Authoring Items — Progressive Toggle

A progressive toggle is a hybrid of a progressive and a toggle. It has multiple stages (like a progressive) and an independent active / inactive flag (like a toggle). Both dimensions are visible in a single icon and each can change separately.

The classic use case is an item where you want to track two things at once:

  • Which version of the item the player has (a progression)
  • Whether they currently have / are using it (an on/off state)

The ALttPR bow is a good example: you advance stages to mark that you've upgraded Arrows → Silver Arrows, and you toggle the active state to mark whether you currently have arrows to shoot.

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

JSON schema

Parsed in EmoTracker.Data/Items/ProgressiveToggleItem.cs. Matches the progressive_toggle branch in items.json.

Top-level fields

Field Type Required Default Description
type "progressive_toggle" yes Literal string.
stages array yes Ordered list of stage definitions (see below).
initial_stage_idx integer no 0 Zero-based index of the stage the item should start in.
initial_active_state boolean no false Whether the item starts active.
swap_actions boolean no false If true, left click advances the stage and right click toggles active.

Per-stage fields

Each entry in stages is its own object. Unlike the progressive type, codes do not inherit across stages — each stage advertises exactly the codes declared on it.

Field Type Required Default Description
img string yes Path (relative to pack root) to the active-state image for this stage.
img_mods string no Image filter spec applied to img.
disabled_img string no derived Path to the inactive-state image for this stage. Derived from img + disabled filter if omitted.
disabled_img_mods string no inherited Image filter spec applied when deriving / loading the inactive image.
codes string yes Public codes this stage provides while active. Inactive stages provide nothing.
secondary_codes string no Pack-internal "private" codes (not exposed to logic checks). Useful if you want to match against a stage from another item or a script without affecting public logic.

Mouse behavior

Button swap_actions: false (default) swap_actions: true
Left click Toggle active state Advance stage
Right click Advance stage Toggle active state

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

Stages and the active flag are independent

A stage advances whether or not the item is active. An item at stage 2 that's currently inactive will still become stage 3 on advance, and toggling active without changing stages is allowed. The current icon is looked up as (active, stage_idx) from the stage table.

Logic only sees an item's codes when it's active — an inactive progressive toggle provides nothing to has(...) checks. This is what makes it useful for "do I currently have X" tracking: right-click to advance the level you've found, then left-click to toggle whether you actually have it in your inventory right now.

Examples

Bow — arrows vs silver arrows, toggleable

{
  "name": "Bow",
  "type": "progressive_toggle",
  "stages": [
    { "img": "images/items/bow.png",         "codes": "bow" },
    { "img": "images/items/silver_bow.png",  "codes": "bow,silverarrows" }
  ]
}
  • Left click toggles "I have arrows right now" on/off.
  • Right click advances from regular arrows to silver arrows.
  • Logic that checks has("silverarrows") is only true when the bow is both at stage 2 and active.

Mushroom — carried, or given to witch

{
  "name": "Mushroom",
  "type": "progressive_toggle",
  "stages": [
    { "img": "images/items/mushroom.png",      "codes": "mushroom"  },
    { "img": "images/items/powder.png",        "codes": "powder"    }
  ]
}

The first stage represents "have the mushroom"; the second represents "have turned it into magic powder". Toggling active handles "whether you're still carrying it" vs "you turned it in".

Medallion — tracked dungeon assignment

The ALttPR medallion trackers use a progressive toggle where each stage represents a different dungeon assignment ("needed in Misery Mire", "needed in Turtle Rock", "both", etc.), and the active state represents whether you've found the medallion yet:

{
  "name": "Bombos",
  "type": "progressive_toggle",
  "stages": [
    { "img": "images/items/bombos.png",      "codes": "bombos" },
    { "img": "images/items/bombos_mm.png",   "codes": "bombos,bombos_mm" },
    { "img": "images/items/bombos_tr.png",   "codes": "bombos,bombos_tr" },
    { "img": "images/items/bombos_both.png", "codes": "bombos,bombos_mm,bombos_tr" }
  ]
}

Tips and pitfalls

  • No code inheritance. Unlike a progressive, each stage starts with an empty code set. Repeat the base code on every stage (e.g. bow on all bow stages) if you want has("bow") to be true regardless of stage.
  • Inactive stages provide zero codes. If you want an item that still exposes its presence when "inactive", you probably want a plain Progressive instead.
  • secondary_codes is pack-internal. Use it for logic you want scripts or other items to see without polluting the public has(...) namespace.
  • initial_stage_idx is zero-based over your stages list — there's no automatic disabled stage here, so index 0 is your first real stage.

See also

Clone this wiki locally