# Item NFT Catalog And Build Plan

## Goal

Create equippable NFT items for worms and sticks. Items sit in `inventoryslots`, add stat modifiers, display as small pixel-art icons in unit cards, and open into a larger rarity card/profile popup when clicked.

This plan is data-first so the same catalog can feed:

- item contract seed data
- frontend item definitions
- metadata JSON
- icon/card PNG generation prompts
- equip/unequip validation

## Current Stat Keys

- `maxHp`: maximum hit points.
- `healrate`: HP recovered per hour.
- `attack`: damage dealt.
- `shield`: flat damage blocked.
- `spd`: travel speed percent.
- `vamp`: percent of damage healed back when dealing damage.
- `exprate`: percent bonus EXP earned.
- `feerate`: percent fee discount.
- `capacity`: spin/carry capacity, number of loot rolls on return.
- `inventoryslots`: number of equippable item slots.
- `stamina`: percent journey damage reduction.
- `luck`: reserved for later. Do not use in v0 item effects unless explicitly enabled.

## Existing Stick Attribute Resource Effects

These should remain readable as the first item/trait language:

- `blood`: HP item family, default effect `maxHpFlat`.
- `banana`: speed item family, default effect `spdPct`.
- `water`: recovery item family, default effect `healrateFlat`.
- `wood`: damage item family, default effect `attackFlat`.
- `leaf`: fee/tax item family, default effect `feeratePct`.

## Balance Rules For First Item Set

- Common items should feel useful, not mandatory.
- Uncommon items can combine a small primary stat with a small secondary stat.
- Rare items should create recognizable builds.
- Epic items should be build-defining and visibly special.
- Legendary items should be scarce, exciting, and easy to explain.
- Avoid level-up-only stats in item effects where possible.
- Avoid capacity and inventory slot bonuses in common/uncommon. Use them sparingly at epic/legendary because they change economic output directly.
- `luck` is excluded for now.
- Percent effects are whole numbers.
- Flat `shield` is allowed.

## Rarity Type Language

Item type should communicate rarity at a glance. The elemental/resource family still controls the stat fiction, but the object class should mostly belong to one rarity band.

| Rarity | Primary Item Types | Fiction Role |
| --- | --- | --- |
| Common | charms, lockets, pins, buttons, bands, thimbles | small personal trinkets |
| Uncommon | badges, spurs, buckles, medals, wraps | field gear with visible purpose |
| Rare | crowns, relics, seals, crests, named blades/fangs | recognizable build identity |
| Epic | contracts, flasks, armor plates, satchels, pact rings | major equipment or formal power |
| Legendary | one-of-one named artifacts | unique myth items, no generic repeats |

Suggested power budget:

| Rarity | Primary Effect | Secondary Effect | Notes |
| --- | ---: | ---: | --- |
| Common | +4-8 HP, +1 attack, +0.25-0.5 heal/hr, 3-6%, or +1 shield | none | Simple single-stat items |
| Uncommon | +10-14 HP, +2 attack, +0.5-0.75 heal/hr, 7-10%, or +2 shield | small optional | Small combos |
| Rare | +18-28 HP, +3-5 attack, +1-1.5 heal/hr, 12-18%, or +3 shield | small optional | Build identity |
| Epic | +35-50 HP, +6-8 attack, +1.75-2.25 heal/hr, 20-28%, or +4 shield | medium optional | Big but not absurd |
| Legendary | +60-80 HP, +10-14 attack, +3-4 heal/hr, 30-45%, or +5 shield | strong optional | Scarce, iconic |

## Common Items

| ID | Name | Family | Effect | Art Direction |
| --- | --- | --- | --- | --- |
| item_c_blooddrop_charm | Blooddrop Charm | blood | `maxHpFlat: 6` | red drop charm hanging from dark twine |
| item_c_bone_locket | Bone Locket | blood | `maxHpFlat: 4` | off-white locket with red stitch holes |
| item_c_leaf_fee_charm | Leaf Fee Charm | leaf | `feeratePct: 3` | small green charm stamped with a fee slash |
| item_c_banana_runner_locket | Banana Runner Locket | banana | `spdPct: 4` | yellow runner locket with two speed notches |
| item_c_splinter_ring | Splinter Ring | wood | `attackFlat: 1` | rough bark ring with a jagged wooden tooth |
| item_c_rain_locket | Rain Locket | water | `healrateFlat: 0.25` | blue locket with a single water bead |
| item_c_pebble_charm | Pebble Charm | wood | `shieldFlat: 1` | small bark-pebble charm on rough string |
| item_c_rust_pin | Rust Pin | wood | `attackFlat: 1` | rusty pin through bark |
| item_c_leaf_thread_pin | Leaf Thread Pin | leaf | `staminaPct: 3` | green thread pin with tiny leaf stitch |
| item_c_tin_runner_charm | Tin Runner Charm | banana | `spdPct: 3` | tiny yellow runner charm on tin wire |
| item_c_sap_band | Sap Band | wood | `maxHpFlat: 4` | amber sap band |
| item_c_moss_locket | Moss Locket | water | `healrateFlat: 0.25` | damp moss locket with blue shine |
| item_c_fee_ticket_charm | Fee Ticket Charm | leaf | `feeratePct: 4` | folded green ticket charm |
| item_c_bark_button | Bark Button | wood | `attackFlat: 1` | carved bark button with sharp notch |
| item_c_berry_charm | Berry Charm | blood | `vampPct: 3` | red berry charm with cork top |
| item_c_slick_runner_pin | Slick Runner Pin | banana | `spdPct: 5` | glossy yellow speed pin |
| item_c_puddle_locket | Puddle Locket | water | `shieldFlat: 1` | wet blue locket with stone rim |
| item_c_scuffed_leaf_charm | Scuffed Leaf Charm | leaf | `feeratePct: 5` | worn coin charm with leaf mark |
| item_c_wooden_tooth_pin | Wooden Tooth Pin | wood | `attackFlat: 1` | jagged wooden tooth pin |
| item_c_canteen_thimble | Canteen Thimble | water | `healrateFlat: 0.5` | tiny blue thimble charm shaped like a canteen |

## Uncommon Items

| ID | Name | Family | Effect | Art Direction |
| --- | --- | --- | --- | --- |
| item_u_crimson_guard_badge | Crimson Guard Badge | blood | `maxHpFlat: 12` | red shield badge with pale stitch rivets |
| item_u_banana_runner_badge | Banana Runner Badge | banana | `spdPct: 8` | yellow runner badge with tiny wing marks |
| item_u_oak_fang_badge | Oak Fang Badge | wood | `attackFlat: 2` | wood badge mounted with a sharpened oak fang |
| item_u_dew_medal | Dew Medal | water | `healrateFlat: 0.75` | blue droplet medal with silver rim |
| item_u_leaf_fee_badge | Leaf Fee Badge | leaf | `feeratePct: 8` | green field badge stamped with a fee slash |
| item_u_barkwall_badge | Barkwall Badge | wood | `shieldFlat: 2` | square bark shield badge |
| item_u_bloodwood_medal | Bloodwood Medal | blood/wood | `maxHpFlat: 8, attackFlat: 1` | red wooden medal with tooth notch |
| item_u_slickbark_badge | Slickbark Badge | banana/wood | `spdPct: 6, attackFlat: 1` | yellow varnished bark badge |
| item_u_moss_fee_badge | Moss Fee Badge | water/leaf | `healrateFlat: 0.5, feeratePct: 3` | mossy green badge with blue edge |
| item_u_riverguard_pin | Riverguard Pin | wood/water | `shieldFlat: 1, healrateFlat: 0.25` | bark field pin with blue guard dot |
| item_u_red_canteen_badge | Red Canteen Badge | blood/water | `maxHpFlat: 6, healrateFlat: 0.25` | red canteen badge with blue stopper |
| item_u_fee_runner_spurs | Fee Runner Spurs | leaf/banana | `feeratePct: 5, spdPct: 4` | green-yellow runner spurs |
| item_u_splinter_spur_badge | Splinter Spur Badge | wood | `attackFlat: 2` | badge with twin wooden spikes |
| item_u_guardleaf_badge | Guardleaf Badge | leaf/wood | `feeratePct: 4, shieldFlat: 1` | field badge with leaf over bark |
| item_u_sapneedle_badge | Sapneedle Badge | wood/blood | `attackFlat: 1, vampPct: 4` | badge crossed with a red sap needle |
| item_u_coolwrap_badge | Coolwrap Badge | water/banana | `healrateFlat: 0.25, staminaPct: 5` | wet yellow field badge with blue cloth edge |
| item_u_riverstone_buckle | Riverstone Buckle | water/wood | `shieldFlat: 2, staminaPct: 2` | blue-gray bark buckle |
| item_u_barker_blade_badge | Barker Blade Badge | wood | `attackFlat: 2` | bark blade mounted on a field badge |
| item_u_red_lace_medal | Red Lace Medal | blood | `maxHpFlat: 14` | red lace medal knot |
| item_u_slipstream_badge | Slipstream Badge | banana | `spdPct: 10` | yellow runner badge with motion marks |

## Rare Items

| ID | Name | Family | Effect | Art Direction |
| --- | --- | --- | --- | --- |
| item_r_heartwood_relic | Heartwood Relic | blood/wood | `maxHpFlat: 18, attackFlat: 2` | red heart relic set inside carved wood |
| item_r_goldleaf_seal | Goldleaf Seal | leaf | `feeratePct: 15` | green-gold relic seal with wax stamp |
| item_r_haste_crown | Haste Crown | banana | `spdPct: 15` | bright yellow courier crown with blue streak |
| item_r_splinterfang_relic | Splinterfang Relic | wood | `attackFlat: 4` | tooth-shaped wood relic mounted in a dark frame |
| item_r_rainwell_relic | Rainwell Relic | water | `healrateFlat: 1.25` | tiny well relic holding a blue water drop |
| item_r_barkwall_crest | Barkwall Crest | wood | `shieldFlat: 3` | layered bark crest shield |
| item_r_crimson_crown | Crimson Crown | blood | `maxHpFlat: 24` | red survival crown made from cape cloth |
| item_r_mudskipper_relic | Mudskipper Relic | banana/water | `spdPct: 12, staminaPct: 6` | wet yellow speed relic with blue mud marks |
| item_r_taxcut_seal | Taxcut Seal | leaf | `feeratePct: 12, expratePct: 4` | clover seal stamped into green wax |
| item_r_training_fang | Training Fang | wood | `attackFlat: 2, expratePct: 8` | carved twig fang with tally marks |
| item_r_bloodberry_relic | Bloodberry Relic | blood | `maxHpFlat: 12, vampPct: 8` | red berry relic in a dark frame |
| item_r_saltwater_crest | Saltwater Crest | water | `healrateFlat: 0.75, staminaPct: 8` | blue-white wave crest |
| item_r_anchor_relic | Anchor Relic | water/wood | `shieldFlat: 2, staminaPct: 6` | chipped driftwood anchor relic |
| item_r_merchant_seal | Merchant Seal | leaf | `feeratePct: 10, capacityFlat: 1` | green seal with small bag mark |
| item_r_runner_crown | Runner Crown | banana | `spdPct: 14, expratePct: 4` | yellow courier crown with knot marks |
| item_r_oakjaw_relic | Oakjaw Relic | wood | `attackFlat: 5` | wooden jaw relic with tooth frame |
| item_r_redroot_crown | Redroot Crown | blood | `maxHpFlat: 28` | root crown with red eye gem |
| item_r_bluesalve_relic | Bluesalve Relic | water | `healrateFlat: 1.5` | blue salve relic in a round tin frame |
| item_r_fee_crest | Fee Crest | leaf/wood | `feeratePct: 14, shieldFlat: 1` | green bark crest with fee mark |
| item_r_moon_courier_crown | Moon Courier Crown | banana | `spdPct: 18` | pale yellow courier crown with crescent notch |

## Epic Items

| ID | Name | Family | Effect | Art Direction |
| --- | --- | --- | --- | --- |
| item_e_blood_oath_contract | Blood Oath Contract | blood | `maxHpFlat: 42` | red oath contract with black rim and cut gem center |
| item_e_storm_courier_contract | Storm Courier Contract | banana | `spdPct: 25` | yellow speed contract with electric blue inlay |
| item_e_ironwood_war_contract | Ironwood War Contract | wood | `attackFlat: 7` | dark war contract pinned with an ironwood fang |
| item_e_springheart_flask | Springheart Flask | water/blood | `healrateFlat: 1.5, maxHpFlat: 16` | glass flask with red-blue liquid glow |
| item_e_mound_contract | Mound Contract | leaf | `feeratePct: 22, expratePct: 6` | glowing green contract with a gold mound seal |
| item_e_barkwall_plate | Barkwall Plate | wood | `shieldFlat: 4` | thick bark armor plate |
| item_e_vampire_pact_ring | Vampire Pact Ring | blood/banana | `vampPct: 12, spdPct: 10` | red pact ring with yellow speed tail |
| item_e_grinder_contract | Grinder Contract | wood | `expratePct: 18, attackFlat: 2` | training contract with tally marks |
| item_e_courier_satchel | Courier Satchel | banana/leaf | `spdPct: 18, feeratePct: 8` | green-yellow courier satchel |
| item_e_deep_moss_armor_plate | Deep Moss Armor Plate | water/wood | `shieldFlat: 3, healrateFlat: 0.75` | moss armor plate with blue growth |
| item_e_heart_bark_flask | Heart Bark Flask | blood/wood | `maxHpFlat: 28, attackFlat: 3` | red bark flask with wooden stopper |
| item_e_luckyless_contract | Luckyless Contract | leaf | `feeratePct: 28` | formal green contract with crossed fee mark |
| item_e_rocket_spur_satchel | Rocket Spur Satchel | banana | `spdPct: 28` | yellow satchel with paired rocket spurs |
| item_e_war_contract | War Contract | wood | `attackFlat: 8` | blackened contract sealed with a twig spear |
| item_e_calm_flask | Calm Flask | water | `healrateFlat: 2.25` | polished blue flask with still water glow |
| item_e_pact_ring | Pact Ring | leaf/blood | `feeratePct: 12, maxHpFlat: 20` | green ring with red bead |
| item_e_prize_satchel | Prize Satchel | leaf | `capacityFlat: 1, feeratePct: 8` | tiny satchel with leaf clasp |
| item_e_double_pocket_satchel | Double Pocket Satchel | leaf | `inventoryslotsFlat: 1, staminaPct: 8` | stitched green satchel with two pockets |
| item_e_guardian_sap_plate | Guardian Sap Plate | wood | `shieldFlat: 2, attackFlat: 3` | amber sap armor plate with bark edge |
| item_e_fastblood_pact_ring | Fastblood Pact Ring | blood/banana | `maxHpFlat: 20, spdPct: 14` | red pact ring with yellow trail |

## Legendary Items

| ID | Name | Family | Effect | Art Direction |
| --- | --- | --- | --- | --- |
| item_l_crown_of_the_mound | Crown of the Mound | wood/blood/banana | `maxHpFlat: 40, attackFlat: 6, spdPct: 15` | tiny dirt crown with blood jewel and yellow courier prongs |
| item_l_blood_sun_relic | Blood Sun Relic | blood | `maxHpFlat: 80` | red sun relic with black rays and bright center |
| item_l_comet_courier_ring | Comet Courier Ring | banana | `spdPct: 45` | yellow comet ring with a blazing speed tail |
| item_l_worldroot_axe | Worldroot Axe | wood | `attackFlat: 14` | massive root axe with wrapped bark handle |
| item_l_living_spring_relic | Living Spring Relic | water | `healrateFlat: 3, vampPct: 8` | blue spring relic in a silver water frame |
| item_l_founders_writ | Founder's Writ | leaf | `feeratePct: 40, expratePct: 10` | gold-veined founding document with green seal |
| item_l_aegis_of_bark | Aegis of Bark | wood/blood | `shieldFlat: 5, maxHpFlat: 28` | radiant bark aegis with red heart grain |
| item_l_grinders_crown | Grinder's Crown | wood | `expratePct: 35, attackFlat: 3` | crowned artifact with tally teeth |
| item_l_vampire_root | Vampire Root | blood/wood | `vampPct: 18, attackFlat: 5` | red root claw gripping dark wood |
| item_l_courier_star | Courier Star | banana/leaf | `spdPct: 30, feeratePct: 18` | star artifact with courier wings and green stamp |
| item_l_font_of_return | Font of Return | water/blood | `maxHpFlat: 50, healrateFlat: 1.5` | red-blue healing font with silver rim |
| item_l_void_tithe | Void Tithe | leaf | `feeratePct: 50` | black-green tithe artifact swallowing a receipt |
| item_l_threefold_satchel | Threefold Satchel | leaf | `capacityFlat: 2` | named three-pocket artifact satchel glowing green |
| item_l_hammersplinter | Hammersplinter | wood | `attackFlat: 9, shieldFlat: 3` | hammer-shaped root artifact with splinter head |
| item_l_bottomless_pocket | Bottomless Pocket | leaf | `inventoryslotsFlat: 2` | impossible stitched pocket with green interior glow |
| item_l_redline_treads | Redline Treads | banana/blood | `spdPct: 28, maxHpFlat: 32` | named red-yellow speed artifact with blood laces |
| item_l_egg_tithe_seal | Egg Tithe Seal | leaf | `feeratePct: 25, capacityFlat: 1` | ancient seal with egg mark and green wax |
| item_l_hero_splint | Hero Splint | blood/wood | `maxHpFlat: 55, shieldFlat: 3` | red medical artifact splint with bark brace |
| item_l_overclocked_root | Overclocked Root | wood/banana | `attackFlat: 8, spdPct: 20` | sparking root artifact with yellow current |
| item_l_mythic_moss_relic | Mythic Moss Relic | water/leaf | `healrateFlat: 2, staminaPct: 20, inventoryslotsFlat: 1` | glowing moss relic in a leaf-water frame |

## PNG Asset Plan

Each item needs two generated visual assets:

- Icon PNG: 64x64 transparent pixel-art item icon.
- Card PNG or HTML-rendered card snapshot: 512x716 collectible card with rarity frame, item name, icon, stat text, and optional flavor line.

Recommended approach:

1. Generate icons first from the `Art Direction` column.
2. Store icons under `assets/items/icons/{rarity}/{item_id}.png`.
3. Build card frames in HTML/CSS so rarity styling stays consistent and can be changed without regenerating all cards.
4. Export card PNGs from the HTML renderer only for metadata marketplaces.
5. Store generated card snapshots under `assets/items/cards/{rarity}/{item_id}.png`.

Card fields:

- Item name
- Rarity
- Item family
- Slot: `unit_item`
- Effects, human readable
- Icon
- Optional flavor text

## Contract Plan

Create an `ItemNFT` contract, then wire it into a stats/equipment manager.

For the first testnet item drop, use ERC-1155 capped editions instead of one ERC-721 token per copy. Each item design is one token id with a max supply:

- Common: 200 editions of each item type.
- Uncommon: 100 editions of each item type.
- Rare: 50 editions of each item type.
- Epic: 20 editions of each item type.
- Legendary: 5 editions of each item type.

This keeps the drop table to one package per item design instead of one package per individual copy, while still rendering as NFT item editions on marketplaces that support ERC-1155.

Suggested contracts:

- `ItemNFT`: ERC-1155 capped-edition item tokens, metadata URI, rarity, item type id, and stat effects.
- `UnitEquipmentManager`: equipped items per unit, ownership checks, slot limits, locked state, events.
- `UnitStatsResolver`: include equipped item effects when resolving effective unit stats.

Core item type struct:

```solidity
struct ItemType {
    uint32 itemTypeId;
    uint8 rarity;
    bytes32 family;
    uint32 maxSupply;
    uint32 minted;
    bool active;
    StatEffect[] effects;
    string metadataUri;
}

struct StatEffect {
    bytes32 statKey;
    int32 value;
    uint8 op; // flat, pct
    uint8 decimals; // allows fixed values like healrateFlat 0.25
}
```

Core equip rules:

- Player must own the unit and the item.
- Item must not already be equipped.
- Unit must have free `inventoryslots`.
- Equipped item should be locked from transfer, or transfer should revert while equipped.
- Unequip should be allowed by owner unless item is explicitly soulbound/locked.
- Game actions should snapshot effective stats at send time.

Events:

```solidity
ItemTypeSet(uint32 indexed itemTypeId, uint8 rarity, bytes32 family, bool active)
ItemMinted(address indexed to, uint256 indexed tokenId, uint32 indexed itemTypeId)
ItemEquipped(address indexed unitContract, uint256 indexed unitId, address indexed itemContract, uint256 itemTokenId)
ItemUnequipped(address indexed unitContract, uint256 indexed unitId, address indexed itemContract, uint256 itemTokenId)
```

## Frontend Plan

1. Add item catalog data file generated from this doc.
2. Add item icon renderer/loading helpers.
3. Show equipped item icons on unit cards.
4. Add hover tooltip for each item icon:
   - name
   - rarity
   - stat effects
5. Add item profile popup:
   - full card
   - icon
   - rarity
   - equipped unit, if equipped
   - stat effects
   - equip/unequip button when available
6. Add wallet inventory panel section for item NFTs.
7. Add equip flow:
   - choose unit
   - choose free slot
   - submit tx
   - refresh stats
8. Add debug fixtures:
   - one unit with one item of each rarity
   - one unit with full slots
   - one item that affects each stat

## Build Order

1. Freeze item catalog and stat budgets.
2. Generate `data/item-nft-catalog.json`.
3. Generate first-pass icon PNGs.
4. Add frontend item display and popup using local fixtures.
5. Write `ItemNFT`, `ItemRegistry`, and `UnitEquipmentManager`.
6. Add equipped item effects to `UnitStatsResolver`.
7. Add deploy/setup scripts.
8. Add testnet mint script for admin/dev wallet.
9. Add equip/unequip frontend tx flow.
10. Add indexer support for item ownership and equipped state.

## Open Design Questions

- Should item NFTs be transferable while unequipped only, or always transferable with auto-unequip disallowed?
- Should some legendary items be soulbound?
- Should capacity/inventory bonuses be allowed on launch, or held for later?
- Should worm-only/stick-only item restrictions exist?
- Should items have durability or charges later?
