Meme Wars · Plugin System · Design

Three inventories.
Should there be one?

The game already tracks "things a player is carrying" in three unrelated places, each with its own shape, its own UI, and its own access code. Blocks, ammo, and now seeds all mean the same thing — a count of an item you hold — yet nothing connects them. This asks what a single inventory plugin could be, so the next stackable thing (rations, tools, keys, a cooked meal) is a line of data, not a fourth system.

today  blocks.map · ammo.map · seedbag.n builds on  UI framework A (HUD) + D (menus) unblocks  /give any item · campfire stock+place (12.4)
The problem

Three ways to hold a thing

Each was added when it was needed, and each is fine alone — but they don't share a model, so "how many do I have" and "show it to me" are re-solved every time.

blocks · the trowel's stock
blocks.map[mat] — a per-material count + a selected one; UI is a radial wheel (C) and a panel (I).
ammo · per weapon
10186
ammo.map[weapon] — a per-weapon count; UI is the weapon bar.
seeds · agriculture
SEEDS
3
seedbag.n — a single scalar; UI is a HUD counter.

Same idea, three shapes: a keyed map with a selection, a keyed map, and a bare number. A new stackable — rations, a hoe, a door key — has nowhere to go but a fourth one.


01 · Foundation

AUnify the model, keep the faces

An inventory infrastructure plugin owns one data model — item → count, per player — and blocks, ammo, seeds become entries in it. The existing wheel, weapon bar, and HUD counter keep their looks but read from the one store. Least disruptive; the single source of truth that every other direction sits on.

the plugin writes
local inv = engine.require("inventory")

-- a stack is just an item + a count on a player
inv.add(pid, "dirt", 8)          -- pickup gave blocks
inv.add(pid, "seeds", 3)

if inv.count(pid, "seeds") > 0 then   -- plant control
  inv.take(pid, "seeds", 1)
  plant(pid)
end

-- items declare how they stack once, as data
inv.define("seeds", { stack = 99, icon = "seed", category = "crop" })
one store, three faces
player · inventory
dirt×8
seeds×3
cereal (ammo)×18
ration×1
wheel · weapon bar · HUD all read this
Strength

One model, one add/take/count. Every current UI keeps working; a new stackable is a define + add. Fixes /give (route through it) and the campfire stock (12.4) for free.

Limit

No new player-facing UI by itself — it's plumbing. The "see everything in one place" want (below) still needs a face.

Cost

Medium: migrate blocks/ammo/seeds onto it without changing how they feel. The prerequisite for B–D.


02 · The classic

BOne bag, a grid of slots

A single panel (a key opens it) shows everything you hold — blocks, seeds, ammo, food — as icon slots with counts, grouped by category. The survival/RPG bag: one place, scannable, room to grow. Built as a new UI-framework template fed by the inventory store.

the plugin writes
-- the bag is a template over the inventory store
plugin.bag({
  open = "KeyB", title = "Backpack",
  categories = { "blocks", "crop", "food", "ammo" },
})

-- clicking a slot fires its item's "use", if it has one
inv.define("ration", { icon = "food", category = "food",
  use = function(pid) eat(pid, 45) end })
what the player sees
AllBlocksCropsFood
8
3
🌱3
🌿2
🍖1
🍗1
B · one place to see it all
Strength

The obvious "what am I carrying" answer, and it scales — dozens of item types with no new UI each. Categories keep it legible.

Limit

A modal grid is slower than a wheel for a twitch shooter; opening a bag mid-fight is a pause you didn't ask for. Best as the deep view, not the quick one.

Cost

Medium–high: a new grid template + slot interactions, on top of A.


03 · Action-game

CA hotbar for what's in hand

A row of quick slots along the bottom — the few things you actually use in the moment (a weapon, seeds, a ration, a campfire kit). Number keys or the scroll wheel pick the active one; the full bag (B) sits behind it. Keeps hands on the fight.

the plugin writes
plugin.hotbar({ slots = 6, keys = "1..6" })

-- an item can ask to sit on the hotbar by default
inv.define("campfire", { icon = "fire", hotbar = true,
  use = function(pid) place_campfire(pid) end })

-- "use active slot" is a control the player rebinds
plugin.control("use", { default = "KeyF" }, function(pid)
  inv.use_active(pid)
end)
what the player sees
1🔫18
2🌱3
3🔥1
4🍖1
58
6
C · active slot glows · F uses it
Strength

Fast and always-visible; the fight never stops to open anything. Folds the weapon bar, seed counter, and campfire kit into one familiar strip.

Limit

Only a handful of slots — needs the bag (B) behind it for everything else, and a rule for what auto-lands on the bar.

Cost

Medium: a hotbar strip + slot assignment + "use active", on top of A. Naturally pairs with B.


04 · Native to the game

DCategory wheels, the way we already pick things

The game already picks blocks and cooking actions with a radial. Lean all the way in: an inventory is a set of category wheels — a blocks wheel, a consumables wheel — each on a key, each a UI-framework menu fed by the store. No new widget vocabulary; it just is the framework we built.

the plugin writes
-- a wheel is a template menu whose options ARE a category
plugin.menu("consumables", {
  template = "radial", open = "KeyQ",
  from = { inventory = "food" },   -- auto-filled from the store
}, function(pid, item) inv.use(pid, item) end)
what the player sees
Eat
🍖ration
×1
🌿produce
×2
🍗cooked
×1
D · Q wheel · same as blocks & cooking
Strength

Zero new UI concepts — reuses framework D exactly, so it's consistent with the block wheel and cooking menu, and fast to open.

Limit

A wheel gets crowded past ~8 items, and it's a picker, not an overview — you can't see everything at once the way a bag shows it.

Cost

Low: mostly "let a menu's options come from an inventory category", on top of A + the existing D.


Recommendation

Model first, then a face per speed

A is not optional — it's the thing the other three stand on, and it's what actually retires the three-implementations problem. The face is then a small choice you can make late, and change.

A path

  1. Build A — the inventory model. One inventory plugin: define / add / take / count, item categories + icons. Migrate blocks, ammo, and seeds onto it so nothing feels different. This alone fixes /give <anything> and lets the campfire kit become a stocked item you place (Set 12.4).
  2. Add D (category wheels) for quick use. Cheapest, and native — an inventory category is just a template menu whose options come from the store. Seeds/consumables/blocks become wheels like the ones we already have.
  3. Add C (a hotbar) if the fight wants it — the few in-hand items, always visible, number-keyed. Folds the weapon bar + seed counter + campfire kit into one strip.
  4. Add B (the bag) as the deep view when the item count outgrows wheels — the scannable "everything I own", not the quick picker.

The through-line: an inventory plugin is a data model plus UI-framework declarations — HUD counts (A), template menus/wheels (D), and later a grid template (B). It doesn't invent a new system so much as it collects the three we already have and hands the next stackable a home.

Meme Wars · inventory plugin — design directions for review. Companion to the Plugin UI Framework directions and the Field Codex. Nothing here is built yet; this is the shape we'd commit to.