← Back to Blog
Inventory and Crafting Systems for Browser Games
InventoryCraftingGame Design · 11 min read
An inventory system seems simple until you build one. Suddenly you're dealing with stack limits, drag-and-drop, item rarity tiers, equipment slots, recipe discovery, and a save format that won't explode when you add new items in a patch. Here's how to build inventory and crafting systems that scale from a weekend prototype to a full farming simulation.
Data-Driven Item Definitions
Never hardcode item properties. Define all items in a single JSON file (or module) with entries like:
- id — unique string, never reuse or rename:
"wheat_seeds"
- name — display name:
"Wheat Seeds"
- category — for filtering tabs:
"seeds", "crops", "tools", "food"
- stackMax — how many fit in one slot: 99 for seeds, 1 for tools
- rarity — common, uncommon, rare, legendary (drives UI color and sort order)
- sellPrice — base sell value in gold
- icon — sprite sheet coordinates or image path
The inventory itself only stores { itemId: "wheat_seeds", quantity: 47 } — never duplicate the full item definition in each slot. Look up the definition by ID when you need display info.
Slot-Based Inventory Grid
The standard approach: a fixed-size array of slots, each holding an item ID and quantity (or null if empty). Grid sizes of 20–40 slots work well for most games. Provide a way to expand (buy more slots, unlock a backpack upgrade) for progression.
| Design Decision | Tradeoffs |
| Fixed grid (Minecraft-style) | Familiar UI, spatial memory, but wastes space |
| Scrollable list | Infinite items visible, but loses spatial feel |
| Category tabs + grid | Best of both for games with many item types |
| Weight-based (no slots) | Realistic, but harder to visualize |
Drag and Drop
Drag-and-drop is the expected interaction for inventory management. For browser games, you have two approaches:
- HTML drag events — use
draggable="true" on slot elements, handle dragstart/dragover/drop. Works well for DOM-rendered inventories. Mobile support requires the Drag-and-Drop polyfill for touch events.
- Canvas/WebGL pickup — on mousedown, store the slot index and item. Render a floating sprite at the cursor. On mouseup, detect which slot (or the ground/trash) the cursor is over. More work, but integrates seamlessly with canvas-rendered games.
Key behaviors to implement:
- Swap items when dropping onto an occupied slot with a different item
- Merge stacks when dropping onto the same item type (respecting stackMax)
- Split stacks on right-click-drag or shift-click (take half)
- Return item to original slot if dropped outside valid targets
The Crafting System
Crafting transforms input items into output items according to recipes. The data structure is straightforward:
Each recipe has: inputs (array of {itemId, quantity}), output ({itemId, quantity}), station (optional — which crafting table/furnace is required), and unlocked (whether the player has discovered this recipe).
Recipe Discovery
Three common approaches:
- All recipes visible — simplest. The player sees every recipe from the start. Grayed-out recipes show what materials they're missing. Works for casual games.
- Unlock by obtaining ingredients — when the player first picks up Iron Ore, all recipes containing Iron Ore become visible. Creates natural progression tied to exploration.
- Experimentation — the player places items in a crafting grid and discovers recipes by trying combinations. Rewarding but frustrating without hints. Best combined with a recipe book that records discoveries.
Crafting UI Patterns
The two dominant patterns:
- Recipe list (Terraria/Stardew style) — scrollable list of available recipes, filtered by crafting station. Click to craft. Shows required materials with "have/need" counts. Simple, efficient, mobile-friendly.
- Grid crafting (Minecraft style) — place items in a grid pattern to discover recipes. Spatial and experimental, but requires memorizing or looking up recipes. Better for sandbox games.
Batch crafting: Always support "craft 1 / craft 5 / craft all" buttons. Nothing kills the flow of a farming game like clicking "craft" 47 times to turn wheat into flour.
Equipment and Loadout Slots
Separate your inventory grid from equipment slots. Equipment slots are named positions (head, body, tool, accessory) that accept only items matching their type. Equipping an item moves it from inventory to the equipment slot; unequipping moves it back. If inventory is full when unequipping, block the action and show a message.
For farming games, the "tool belt" (a row of slots for active tools/items) is the main equipment interface. The currently selected slot determines what the player does when they click on the world — water with the watering can, plant with seeds, harvest with the sickle.
Sorting and Filtering
As the player accumulates items, manual organization becomes tedious. Provide:
- Auto-sort button — sorts by category, then rarity, then name. Compresses stacks (combines partial stacks of the same item).
- Category tabs — All, Seeds, Crops, Tools, Food, Materials, Quest Items
- Search — for inventories with 100+ unique items, a text filter is essential
- Favorites — let players star items to pin them to the top or a dedicated bar
Save Format and Migration
Your inventory save format will change as you add items and features. Plan for it:
- Store a
version field in the save data
- Save item IDs as strings, not indices — index-based saves break when you insert new items
- Write migration functions:
v1_to_v2(save) that renames deprecated items, adds new default slots, or converts old format quirks
- Test every migration path: v1→v3 should produce the same result as v1→v2→v3
Farming Game Specifics
Farming games have unique inventory challenges:
- Quality tiers — a Normal Tomato and a Gold-Star Tomato are the same item with different quality. Store quality as a property alongside itemId and quantity. Don't create separate item IDs for each quality level — it explodes your item database.
- Seasonal availability — seeds that can only be planted in spring shouldn't be craftable or buyable in winter. Tie item availability to the calendar system.
- Shipping bin — a special "inventory" that converts to gold at end-of-day. Satisfying to dump items into; serves as both a sell mechanism and a daily revenue tracker.
- Gift giving — NPCs have gift preferences. Tag items with gift data (loved/liked/neutral/disliked) per NPC.
A Full Inventory in the Browser
FarmHeart features a complete inventory, crafting, and equipment system — hundreds of items, all running in your browser.
Play FarmHeart Now