Expansion packs: items, equipment and shops
items.toml adds new consumables and equipment to an expansion pack, groups equipment into sets with bonuses for wearing them together, and opens the pack's own shops. Every hook is the identity with no pack active (or a pack with no items): nothing is compiled, no stat changes, no alias is lent, and a save carries no item record.
At a glance
- File
items.tomlat the pack root; optional. Declaresitem,item_setandshopids.- Parser
legaia_expansion_format::items(alsoItemRef, the retail-or-pack item reference).- Runtime
legaia_engine_expansion::{items, item_screen};engine-core'sworld::expansion_itemswires them to theWorld.- Referenced from
- battle.toml drops, steals and boss rewards; level rewards; quest rewards and
collect_item; mapshoptriggers and shop NPCs. - Save
- Tail record
4of the pack'sLXP1expansion block.
Where pack items live
Retail's item id is a u8, and the static item table leaves 0x00 ("no item") and four cut slots blank (0x12, 0x52, 0xB9, 0xFD), and 0x1A holds a party-named string no pool or item in play uses. Those last five are spare. A pack item cannot take a retail id without displacing a real item, and five spare ids are too few for a gear set, so pack items live in their own store, keyed by their items.toml key.
| What | Retail | Pack |
|---|---|---|
| The bag | 256 [id, count] slots at 0x80085958 | ItemProgress::bag, key to count (cap 99) |
| Worn gear | The record's equipment bytes +0x196..+0x19D | ItemProgress::worn, (hero, byte) to key |
| Saved in | The SC block | The expansion block, tail record 4 |
Neither retail structure ever holds a pack item, which keeps a retail save's bytes and a no-pack session untouched. The retail Items and Equip screens therefore do not list pack items; the pack item screen does.
Battle aliases
A fight needs a u8 for the pack items in it: a drop byte, a steal entry, an Item command row. For one fight the engine lends the five cut ids to those pack items - each pack drop and steal of the seated monsters first, then each battle-usable pack consumable held - with a catalog entry each, so the retail drop roll, steal, Item command, handler and results window all work on them unchanged. A grant or consume of an alias goes to the pack bag. At most five pack items take part in one fight.
items.toml
[items.vigil_blade]
name = "Vigil Blade"
kind = "weapon"
icon = { kind = "item", id = 0x27 }
characters = ["vahn"]
attack = 112
set = "vigil"
[items.phoenix_plume]
name = "Phoenix Plume"
kind = "consumable"
price = 12000
effect = { kind = "revive", percent = 50 }
all_party = true
[sets.vigil]
bonuses = [{ pieces = 2, attack = 10 }, { pieces = 4, passives = [0x24] }]
[[shops]]
id = "tower_armory"
stock = ["phoenix_plume", 0x79, { item = "vigil_crown", requires = { bosses = ["iron_regent"] } }]
| Key | Meaning |
|---|---|
name, description | Menu name (at most 20 characters) and info line (| breaks it). |
kind | consumable, weapon, armor, helmet, boots, accessory or key. |
icon | A retail item whose look the item borrows: its icon, and for equipment the battle mesh and swing. |
price, sell | Buy price (0 never sold); sell price, half the buy price by default. |
characters | Who may wear it (vahn, noa, gala); everyone when empty. |
attack, defence, udf, ldf, speed, intelligence | Flat bonuses while worn. |
element, passives | An element guarded (the retail guard passive 0x1D + element) and passive indices granted while worn. |
set | The set the item belongs to. |
effect, all_party, field, battle | A consumable's effect, whether it covers the party, and where it is usable. |
Each effect is a retail item handler: heal_hp / heal_mp (an amount or full), revive (a percent of max HP), cure (one ailment), cure_all, damage, and as_item, which runs a retail item's own handler (a stat raise, a battle buff, Fury Boost). A set tier applies while one hero wears at least pieces of the set, and tiers stack. A shop row is an item reference or { item, requires, price }: requires lists it only while the quest-prerequisite gate holds.
Item references
Everywhere a pack names an item it writes an ItemRef: an integer (0x79, a retail id), an item coordinate ({ kind = "item", id = 0x79 }), or a string ("vigil_blade", a pack item). Drops, steals, boss and level rewards, quest rewards, collect_item objectives and shop stock all take it.
Runtime
- Grants and counts. A reward lands a retail id in the retail bag and a pack item in the pack bag with a
Got Xtoast; acollect_itemcounts the bag its reference names. - Wearing. A pack item empties its retail byte (the retail item there goes to the bag); a retail item later equipped over it sends the pack item back.
- The stat fold. The battle seed adds worn pack gear as retail gear: ATK into the slot's per-swing byte, UDF / LDF / SPD into the seeded lines, passives and set tiers into the record's ability bits. INT stays menu-only, as retail head gear's does.
- Look. A worn pack item's
iconfills its empty byte for the battle mesh, swing costs and command chips. - Consumables. In battle, held pack consumables join the Item command under their aliases; in the field, the bag's Items tab uses them.
The item screen
The pack item screen owns the frame under SceneMode::Expansion, as the card screen does, so both play hosts draw it from one composition. A map's { kind = "shop" } trigger or a shop NPC opens a counter (Buy / Sell); the Journal's Items page opens the bag (Items / Gear). The Gear tab's member step shows what the slot holds now and the five equipment-fed stats before and after, green up and red down.
Saves
The pack bag and the worn gear are pack progress: they save, park and adopt with the pack's LXP1 block as tail record 4 (u16 bag entries of key + count, then u16 worn entries of hero + byte + key). The record is written only while something is held or worn, and a save made with no pack carries no block at all. Without the pack a worn pack item's retail byte stays empty; it is back when the pack is.
Validation
Errors: an empty or over-long name, a stat outside -255..=255, a passive past 0x3F, an element past 6, an unknown set, a consumable with no effect or usable nowhere, a heal with no amount, a bad revive percent, an icon or as_item that is not an item, a shop row naming an unknown pack item, a map shop naming no shop. Warnings: equipment with no icon, misplaced fields, a set with one member, a pack row with no price.
Limits
- At most five pack items take part in one fight.
- Pack gear is worn by the three heroes only.
- The retail Items and Equip screens list no pack items; a slot a pack item fills shows that item's name on the Equip and Status screens.
The sample pack's gear
The sample pack's gear is set against retail's endgame Ra-Seru set from the static equipment table. Each Vigil piece is about 12-15% above its Ra-Seru twin:
| Slot | Retail best | Sample pack |
|---|---|---|
| Weapons | Ra-Seru Blade 98, Fangs 96, Club 100 | Vigil Blade 112, Talon 110, Maul 114 (boss rewards) |
| Body | Ra-Seru Armor 83/82, Robe 84/78, Plate 75/84 | Vigil Mail 94/94, Robe 95/88, Plate 86/96 |
| Head | Ra-Seru head gear UDF 62-64 | Vigil Crown UDF 71, INT 70 |
| Feet | Ra-Seru Thongs ATK 88, LDF 64, SPD 32 | Vigil Greaves ATK 98, LDF 70, SPD 35 |
The set adds +10 ATK at two pieces, +12 defence at three and All Guard at four. Accessories pair two retail passives at the pair's price; consumables extend the retail line (2,500 HP, 300 MP, a party revive, a party full heal). The 5F Tower Armory opens its stock boss by boss.
See also
- Expansion packs · battles · quests and saves · maps
- Inventory - the retail bag pack items live beside.