Skip to content

KBVEItemDB

Game-agnostic item database + inventory + Mass bridge. The data/inventory half to KBVEGameplay’s effect half:

  • FKBVEItemDef / FKBVEItemFood — runtime item def: identity, type flags, rarity, stacking, prices, tags, and consumable/food effect fields (heals / restoreMana / restoreEnergy / regenPerSecond / regenDuration / cooldown / animationRef) — aligned to FKBVEEffectSpec so a game maps item → effect.
  • UKBVEItemDatabase (GameInstance subsystem) — loads Content/Data/itemdb-data.json via UE Json; lookup by key / ref. Mirrors the chuckItemDB pattern.
  • FKBVEInventory / FKBVEInventoryBag / FKBVEInventoryStack + UKBVEInventoryLibrary (TryAdd / CountItem / FindFirstSlot) — generic inventory model.
  • FKBVEDroppedItemFragment / FKBVEDroppedItemTag — Mass fragment for world-dropped items (key, count, rarity, lifetime, magnet/pickup radius).

Item DATA stays in the shared itemdb MDX. KBVEItemDB carries it + the inventory model; KBVEGameplay applies the consumable effects (atlas/icon rendering deferred).

type_flags classify the consumable — FOOD (0x08) / DRINK (0x10) / POTION (0x20) — and the food: block carries the numbers: heals / restore_mana / restore_energy (instant), regen_per_second + regen_duration (heal-over-time), plus top-level cooldown. A consumer builds an FKBVEEffectSpec from these (instant Restores + Regens, cooldown-gated) and applies it through KBVEGameplay’s UKBVEEffectComponentIKBVEStatTarget. Type picks the regen target (food → health, drink → mana/stamina); the data fills the magnitudes. An item with a food: block or a food/drink/potion type bit is consumable without needing an explicit consumable: true.

Dropped items (AKBVEDroppedItemActor / UKBVEDroppedItemPool)

Section titled “Dropped items (AKBVEDroppedItemActor / UKBVEDroppedItemPool)”

Pooled, billboarded world-drop system — extracted from chuck’s chuckDroppedItemActor / chuckDroppedItemPool and made game-agnostic.

  • AKBVEDroppedItemActor — sphere overlap root + icon/halo UMaterialBillboardComponent
    • rarity UPointLightComponent. Idle bob, then pawn-overlap triggers a homing ease toward the picker; on complete it calls back into the pool. No game types.
  • UKBVEDroppedItemPool (world subsystem) — preallocates InitialPoolSize (64) actors, free-list SpawnDrop / ReleaseDrop, fires OnItemPickedUp(Picker, ItemKey, Count) on homing-complete so the game owns auth + inventory add.
  • IKBVEDroppedItemVisualProvider (icon-provider seam) — game implements GetDroppedItemVisual(ItemKey, FKBVEDroppedItemVisual&) to supply per-item IconMID / HaloMID / RarityColor; registered via SetVisualProvider. Keeps atlas/MID generation game-side while the pool stays generic.

The chuck-specific Cast<AchuckCoreCharacter> + ServerAddItemByKey pickup path becomes: provider feeds visuals, OnItemPickedUp delegate feeds the inventory.

chuck now consumes this directly — UchuckItemDB implements IKBVEDroppedItemVisualProvider (maps key → atlas icon MID + rarity halo) and hosts the OnItemPickedUp handler (HandleDroppedItemPickedUp → authority-gated ServerAddItemByKey); AchuckCoreCharacter::BeginPlay registers the DB as the pool’s provider + pickup sink once, and ServerDropSlot just calls SpawnDrop(ItemKey, Count, Loc). chuck’s old chuckDroppedItemActor / chuckDroppedItemPool are deleted.

Generated proto types (gen-itemdb-uecpp.mjs)

Section titled “Generated proto types (gen-itemdb-uecpp.mjs)”

The same itemdb.binpb descriptor that feeds the zod generator also feeds a UE C++ emitter (packages/data/codegen/gen-itemdb-uecpp.mjs, run via nx run astro-kbve:sync:itemdb-uecpp). It writes, into Public/Generated/:

  • KBVEItemDBProtoTypes.h — one USTRUCT per item-package proto message (FKBVEGenItem, FKBVEGenFoodInfo, FKBVEGenUseEffect, …), topo-ordered so definitions precede use; scalars/enums/nested/repeated map to UE types.
  • KBVEItemDBProtoParse.hKBVEItemDBProto::Populate(FStruct&, yyjson_val*) per message, reading the camelCase JSON keys the data codegen emits.

So a new proto field regenerates both the struct and its JSON reader — no hand-written parser to drift (the class of bug that silently dropped consumable data). The mirror of the zod generator, emitting UE-native USTRUCTs instead of google::Message (no libprotobuf runtime). Pilot: generated + compiled by the KBVEItemDB build; chuck keeps its hand-parser until it migrates onto these.

Persistence (FKBVEInventoryStore / UKBVEInventoryStoreSubsystem)

Section titled “Persistence (FKBVEInventoryStore / UKBVEInventoryStoreSubsystem)”

Durable local inventory via the KBVESQLite plugin — row-per-slot (player_inventory(player_id, bag_ref, slot_idx, item_key, count, durability, flags), WAL), save/load/count/clear by player id, opened at Saved/KBVE/inventory.db.

Two boundaries to respect:

  1. SQLite ⟂ Mass. SQLite is a persistence boundary, not a per-tick datasource: load → seed Mass fragments at spawn/login, mutate fragments on worker threads, flush fragments → SQLite at intervals/logout (game thread / async). A single sqlite3* is not thread-safe; never query it inside the Mass processor loop.
  2. KBVESQLite ⟂ UE SQLiteCore. KBVESQLite is the single sqlite provider for KBVE code (its own vendored sqlite3). Do not also link the engine’s SQLiteCore in the same module — duplicate sqlite3_* symbols crash the build/run. Plugins depending on KBVESQLite declare dependency_plugins: packages/unreal/KBVESQLite.