Skip to content

Track a quest ​

Goal ​

Three simulated deliveries complete a quest and unlock its follow-up.

Files you will edit ​

  • src/game.ts

Steps ​

  1. Use this isolated definition in the template shell. D stands in for a delivery event; in the real game, call progress only after validating a delivery on the authority, for example after removing an item from a bag.

    ts
    import { createQuests, defineGame, type GameContext } from 'gameable';
    
    const quests = createQuests({
      owners: 1,
      quests: [
        { id: 'deliver', objectives: [{ id: 'parcels', target: 3 }] },
        { id: 'return', requires: ['deliver'], objectives: [{ id: 'home' }] },
      ],
    });
    const model = { bars: { parcels: { value: 0, max: 3 } }, message: 'active' };
    function deliveries(ctx: GameContext): void {
      if (ctx.input.pressed('KeyD')) quests.progress(0, 'deliver', 'parcels');
      model.bars.parcels.value = quests.value(0, 'deliver', 'parcels');
      model.message = quests.status(0, 'return');
      ctx.hud.set(model);
    }
    export default defineGame({
      init() {
        quests.reset();
        quests.start(0, 'deliver');
      },
      systems: [{ run: deliveries, on: 'authority' }],
      snapshot: () => quests.snapshot(),
      restore: (state) => quests.restore(state),
    });
  2. Start the follow-up with quests.start(0, 'return') when the player accepts it; availability does not auto-start it. Owners are seat indices. Quest callbacks run synchronously: progress, objective done, complete. Progress clamps at the target and only changes active quests. No step method is needed; the delivery itself is the event.

Verify ​

sh
npm run dev

Before deliveries the message is locked. Press D three separate times: the parcels meter reads 1, 2, 3, then the message is available. A fourth D leaves it at 3. Reload returns to zero and locks the follow-up again.

See also ​