At a glance

File
items.toml at the pack root; optional. Declares item, item_set and shop ids.
Parser
legaia_expansion_format::items (also ItemRef, the retail-or-pack item reference).
Runtime
legaia_engine_expansion::{items, item_screen}; engine-core's world::expansion_items wires them to the World.
Referenced from
battle.toml drops, steals and boss rewards; level rewards; quest rewards and collect_item; map shop triggers and shop NPCs.
Save
Tail record 4 of the pack's LXP1 expansion 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.

WhatRetailPack
The bag256 [id, count] slots at 0x80085958ItemProgress::bag, key to count (cap 99)
Worn gearThe record's equipment bytes +0x196..+0x19DItemProgress::worn, (hero, byte) to key
Saved inThe SC blockThe 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"] } }]
KeyMeaning
name, descriptionMenu name (at most 20 characters) and info line (| breaks it).
kindconsumable, weapon, armor, helmet, boots, accessory or key.
iconA retail item whose look the item borrows: its icon, and for equipment the battle mesh and swing.
price, sellBuy price (0 never sold); sell price, half the buy price by default.
charactersWho may wear it (vahn, noa, gala); everyone when empty.
attack, defence, udf, ldf, speed, intelligenceFlat bonuses while worn.
element, passivesAn element guarded (the retail guard passive 0x1D + element) and passive indices granted while worn.
setThe set the item belongs to.
effect, all_party, field, battleA 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 X toast; a collect_item counts 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 icon fills 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:

SlotRetail bestSample pack
WeaponsRa-Seru Blade 98, Fangs 96, Club 100Vigil Blade 112, Talon 110, Maul 114 (boss rewards)
BodyRa-Seru Armor 83/82, Robe 84/78, Plate 75/84Vigil Mail 94/94, Robe 95/88, Plate 86/96
HeadRa-Seru head gear UDF 62-64Vigil Crown UDF 71, INT 70
FeetRa-Seru Thongs ATK 88, LDF 64, SPD 32Vigil 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