The pack
party
function party(): Pack<{ party: typeof api }>
Install the party API (game.party): heroes, levels, gear, the bag, consumables and the shop.
Helpers
CONSUMABLE_EFFECTS
const CONSUMABLE_EFFECTS: Readonly<Record<string, ConsumableEffect>>
The built-in consumables: heal HP, restore MP, cure (counts as used on a standing hero), revive a downed hero, rest (fill both, the whole party).
createParty
const createParty = (def: PartyDef): Party=> …
A party from its definitions.
statsAtLevel
const statsAtLevel = (base: HeroStats, level: number): HeroStats=> …
The default growth: stats at a level, linear, so gear stays the visible power spike.
xpForLevel
const xpForLevel = (level: number): number=> …
The default level curve: experience to reach a level, 12 (l-1)² + 20 (l-1), a level every few fights.
Classes
Party
class Party
A party: heroes, gear, the bag and the gold.
readonly def: PartyDef— The definitions.readonly slots: readonly string[]— The equipment slots each hero has.readonly maxLevel: number— The highest level.readonly inventory: Inventory— The bag, the gold and the gear (slot ids areheroId:slot).heroes: Record<string, HeroState>— Every hero's live numbers, by id.members: string[]— Hero ids in the party, in order.constructor(def: PartyDef)hero(id: string): PartyHero | undefined— A hero's definition.item(id: string): PartyItem | undefined— An item's definition.join(id: string): boolean— Add a hero to the end of the party; false when unknown or already in it.leave(id: string): boolean— Take a hero out of the party (their gear stays on them).standing(): string[]— Members standing (health above 0).gear(id: string): Record<string, string | null>— The gear a hero wears, by slot.max(id: string): HeroStats— A hero's full stats now: the level's growth plus every worn bonus, floored at 1 health and 0 for the rest.element(id: string): string— The element a hero attacks with: theelementSlotitem's, elsenone.healAll(): void— Fill every member's health and magic.clamp(id: string): void— Clamp a hero's pools to their maxima (after gear or a level changed them).xpFor(level: number): number— Experience to reach a level, on this party's curve.levelFor(xp: number): number— The level a total reaches, capped atmaxLevel.xpToNext(id: string): number— Experience a hero still needs for the next level, or 0 at the cap.giveXp(ids: readonly string[], xp: number): LevelUp[]— Give experience to heroes; returns every level gained. Health and magic grow by the gain.get gold(): number— Gold held. Set the gold held (rounded, never below 0).set gold(v: number)— Gold held. Set the gold held (rounded, never below 0).count(id: string): number— How many of an item are in the bag (worn items not counted); 0 for an unknown item.add(id: string, n = 1): boolean— Add items to the bag; false when unknown or there is no room.remove(id: string, n = 1): boolean— Take items from the bag; false when there were not enough.bag(): { item: PartyItem; n: number }[]— Items held, as definitions with counts, in definition order.slotOf(item: PartyItem): string | null— The slot an item is worn in, or null when it is not gear.equip(heroId: string, itemId: string): boolean— Wear an item from the bag; what the slot held goes back in the bag. False when it is not gear or not held.unequip(heroId: string, slot: string): boolean— Take a slot's item off into the bag. False when the slot is empty or the bag is full.apply(effect: string, power: number, pools: Pools, max: HeroStats): EffectResult— A consumable's effect on pools, without the bag: whatusewould do.partyEffect(effect: string): boolean— Whether an effect is used on the whole party.use(itemId: string, heroId: string): EffectResult— Use a consumable from the bag on a hero (on every member for a party effect); one is taken only when it did something.buyPrice(item: PartyItem): number— What the shop charges.sellPrice(item: PartyItem): number— What the shop pays: the sell ratio of the price, rounded down.sellable(item: PartyItem): boolean— Can the shop buy this item.buy(itemId: string, n = 1): boolean— Buy items into the bag: false when unknown, too dear or there is no room.sell(itemId: string): boolean— Sell one from the bag: false when none is held or the shop will not take it.snapshot(): PartySnapshot— The whole party, as plain data.restore(data: unknown): boolean— Read saved data defensively: what fits these definitions is kept, anything else takes the fresh value (unknown heroes and items are dropped, gear in a slot it cannot go in is left off, levels are re-read from experience when missing, pools are clamped). Returns false (and changes nothing) when the data is not a party at all.
Types
ConsumableEffect
interface ConsumableEffect
What a consumable does: to one hero, or (party) to every member at once.
party?: boolean— Used on the whole party rather than one hero.apply(pools: Pools, max: HeroStats, power: number): EffectResult— The effect on one hero's pools, against their maxima.
EffectResult
interface EffectResult
What a consumable did.
pools: Pools— The pools afterwards.applied: boolean— It did something (a heal on a downed hero does nothing; a revive on a standing one does nothing).shown: number | null— A number to show, or null.
HeroState
interface HeroState
A hero's live numbers.
id: string— The hero's id.xp: number— Total experience.level: number— Current level.hp: number— Current health; 0 is down.mp: number— Current magic.
HeroStats
interface HeroStats
A hero's six stats.
hp: number— Most health.mp: number— Most magic points.atk: number— Attack.def: number— Defence.spd: number— Speed.lck: number— Luck.
LevelUp
interface LevelUp
A level gained.
heroId: string— Who.level: number— The new level.from: HeroStats— Stats before.to: HeroStats— Stats after.
PartyDef
interface PartyDef
A party's definitions.
heroes: readonly PartyHero[]— Every hero the party can have.items: readonly PartyItem[]— Every item it can hold.slots?: readonly string[]— Equipment slots each hero has. Default weapon, armor, accessory.slotOf?: (item: PartyItem) => string | null— The slot an item is worn in, or null. Default its kind, when that is a slot.elementSlot?: string— The slot whose item's element a hero attacks with. Defaultweapon.maxLevel?: number— The highest level. Default 10.xpForLevel?: (level: number) => number— Experience to reach a level. DefaultxpForLevel.growth?: (base: HeroStats, level: number) => HeroStats— Stats at a level from level-1 stats. DefaultstatsAtLevel.effects?: Readonly<Record<string, ConsumableEffect>>— Consumable effects, overCONSUMABLE_EFFECTS.sellRatio?: number— What the shop pays as a share of the price. Default 0.5 (rounded down).unsellable?: readonly string[]— Item kinds the shop will not buy. Default quest and key.stack?: number— The most of one item in a stack. Default 99.bag?: { capacity?: number; maxWeight?: number }— The bag: how many stacks and how much weight it holds. Default effectively unlimited.gold?: number— Gold to start with. Default 0.members?: readonly string[]— Hero ids in the party at the start, in order. Default none.
PartyHero
interface PartyHero
A hero the party can have.
id: string— Unique among the heroes.stats: HeroStats— Level-1 stats.
PartyItem
interface PartyItem
An item the party can hold.
id: string— Unique among the items.kind: string— What it is: a kind that names an equipment slot is worn there (seePartyDef.slotOf).element?: string— For a weapon, the element of the wearer's attacks. Defaultnone.bonus?: Partial<HeroStats>— Stat changes while worn.effect?: string | null— For a consumable, a key of the party's effects; null or absent for anything else.power?: number— The effect's strength.price?: number— Shop price in gold. Default 0.weight?: number— Weight in the bag. Default 0.
PartySnapshot
interface PartySnapshot
The whole party as plain data.
v: 1— Format version, 1.heroes: Record<string, HeroState>— Every hero's live numbers.members: string[]— Hero ids in the party, in order.inventory: InventoryState— The bag, the gold and the gear.
Pools
interface Pools
Health and magic now.
hp: number— Current health; 0 is down.mp: number— Current magic.


