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
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.
tsimport { 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. }, });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 callhits.forget(entity)beforectx.despawn(entity)to clear reused ids. The engine snapshots Health; this part snapshots flags and i-frames.
Verify
sh
npm run devH 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.