Skip to content

Deal damage and heal ​

Goal ​

Press H to remove 25 health and J to heal 10, with a short invulnerability window.

Files you will edit ​

  • src/game.ts

Steps ​

  1. Use this isolated game definition in the template shell. The prefab gives the player the built-in Health component; all hits go through one part.

    ts
    import { createDamage, defineGame, Health, prefab, type GameContext } from 'gameable';
    
    const Player = prefab({ health: 100 });
    const model = { bars: { health: { value: 100, max: 100 } }, message: 'Alive' };
    const hits = createDamage({
      capacity: 4096,
      invulnerableSeconds: 0.5,
      onDeath() {
        model.message = 'Dead';
      },
      onRevive() {
        model.message = 'Alive';
      },
    });
    function health(ctx: GameContext): void {
      hits.step(ctx);
      if (ctx.input.pressed('KeyH')) hits.damage(ctx, ctx.player, 25);
      if (ctx.input.pressed('KeyJ')) hits.heal(ctx, ctx.player, 10);
      if (ctx.input.pressed('KeyR')) hits.revive(ctx, ctx.player, 0.5);
      model.message = hits.isDead(ctx.player) ? 'Dead' : 'Alive';
      model.bars.health.value = Health.current[ctx.player];
      ctx.hud.set(model);
    }
    export default defineGame({
      player: { prefab: Player, spawn: [0, 0, 0] },
      init() {
        hits.reset();
        model.message = 'Alive';
      },
      systems: [{ run: health, on: 'authority' }],
      snapshot: () => hits.snapshot(),
      restore: (state) => {
        hits.restore(state);
        // Derived from restored Health on the next system call.
      },
    });
  2. The message is derived from health/death state each step, so restoring a game also restores its display. In combat, pass the attacker's entity as damage's final argument. On despawn always call hits.forget(entity) before ctx.despawn(entity) to clear reused ids. The engine snapshots Health; this part snapshots flags and i-frames.

Verify ​

sh
npm run dev

H changes the meter from 100 to 75; J changes it to 85. A second H within 0.5 seconds removes nothing. Wait between hits until dead: J cannot revive, while R restores 50 health. Healing never exceeds 100.

See also ​