Skip to content

Give the player an inventory ​

Goal ​

Press C to collect coins and B to buy something costing three coins. Overflow is visible.

Files you will edit ​

  • src/game.ts

Steps ​

  1. Use this isolated definition in the template shell. Owner 0 is a seat index, not the player's ECS entity id. Definitions and the HUD are hoisted.

    ts
    import { createInventory, defineGame, type GameContext } from 'gameable';
    
    const bag = createInventory({ owners: 1, slots: 2, items: [{ id: 'coin', stack: 5 }] });
    const model = { bars: { coins: { value: 0, max: 10 } }, message: 'Collect' };
    function inventory(ctx: GameContext): void {
      if (ctx.input.pressed('KeyC')) {
        const overflow = bag.add(0, 'coin', 4);
        model.message = overflow > 0 ? 'Bag full' : 'Collected';
      }
      if (ctx.input.pressed('KeyB')) {
        model.message = bag.remove(0, 'coin', 3) ? 'Bought' : 'Need coins';
      }
      model.bars.coins.value = bag.count(0, 'coin');
      ctx.hud.set(model);
    }
    export default defineGame({
      init() {
        bag.reset();
        model.message = 'Collect';
      },
      systems: [{ run: inventory, on: 'authority' }],
      snapshot: () => bag.snapshot(),
      restore: (state) => bag.restore(state),
    });
  2. In a room, size owners for the seat ceiling and validate the checked message sender on the authority. Send the result to that player's HUD. add returns the amount that did not fit: leave that much in the pickup. remove is atomic; a failed purchase consumes nothing. move merges or swaps slots, and transfer succeeds only when the full amount fits.

Verify ​

sh
npm run dev

Press C three times: the coin meter reads 4, 8, then 10 and says Bag full (two coins overflow). Press B: it reads 7. After spending down to 1, a further B says Need coins and leaves the meter at 1. Reload empties the bag.

See also ​