Inside the service windows: spellbook and inventory

From logic/ui-spellbook.json (Kingmaker.UI.MVVM._VM.ServiceWindows.Spellbook) and logic/ui-inventory.json (…ServiceWindows.Inventory), cross-checked against core-mechanics.json, loot-vendor-math.json and the difficulty presets — build 20212986, patch 2.7.0x.

The character sheet's defence panel has its own anatomy. Its two neighbours run deeper than they look: the spellbook screen is a live re-computation of your daily slot budget, and the inventory is a thin view over four separate item collections.

Your slot table is computed, not stored

Per level tab, the screen adds up:

  1. Base slots from the class spellbook's per-day table (SpellsPerDay.GetCount(casterLevel, spellLevel); a -1 row means zero).
  2. Bonus spells from the casting stat, using the classic PF formula: if castingStatMod ≥ spellLevel > 0, you get (castingStatMod − spellLevel) / 4 + 1 extra slots of that level. For player-faction units the game deliberately uses the permanent stat (temp buffs excluded) — a buff you will lose by tomorrow cannot grant today's slots.
  3. Extra slots stacked as a unit part (UnitPartExtraSpellsPerDay), plus separate domain/favorite special slots when the book HasDomainSlots.

There is also a hard gate most players discover as a surprise: if your casting stat is too low for the level, the slots are simply gone — the rule is castingStat ≥ 10 + spellLevel, evaluated against that same permanent value.

Two book-specific overrides exist in data: standalone mythic books (Angel/Lich) merge into the switcher as their own entry, and Trickster's Magic Hack replaces the whole slot table lookup via its component.

Known vs prepared

Spontaneous casters read one list (GetKnownSpells(level)); prepared casters render memorized SpellSlots with a metamagic overlay where each applied metamagic shifts the effective level (SpellLevelCost). The merged mythic spellbooks show both lists at once — base and mythic tabs over the same unit.

The spell card is a rules preview

Every field on the information panel comes straight from blueprints: name/description through localized text keys, icon via the m_Icon join, school from the spell descriptor components. The DC preview is not stored anywhere — it is recomputed as 10 + spellLevel + castingStatMod, the same formula anatomy behind DC anatomy.

Inventory: four collections wearing one grid

What looks like one bag is several collections: the player grid, the stash (its own view-model), and vendor lists persisted as shared vendor tables. Prices are computed on demand — GetItemBuyPrice/GetItemSellPrice from the vendor math — never cached onto the item.

  • Paper doll: fixed EquipSlotType slots plus four full weapon sets; quick slots bind usable items.
  • Tooltip: aggregates enchantment names off the item's enchantment list, cost and weight from the blueprint, and can link an acquisition trail (where items come from).
  • Encumbrance: strength-based thresholds; whether overload slows you is gated by the active preset's EncumbranceSlowdown flag (difficulty settings).

What this explains

  • Why a temporary +8 to your casting stat does not buy extra fireballs (permanent-value rule) but a permanent tome does.
  • Why domain slots appear as their own pool rather than mixed into the normal grid.
  • Why selling to different vendors can price the same ring differently: the margin lives in the vendor table, not the item.

Related database section: Classes — e.g. Dragon.