AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Health Combat System

skill-bullish0x-gamestudio-health-combat-system · by bullish0x

Health and combat system including damage, healing, armor, status effects, and combat mechanics

No reviews yet
0 installs
34 views
0.0% view→install

Install

$ agentstack add skill-bullish0x-gamestudio-health-combat-system

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-bullish0x-gamestudio-health-combat-system)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Health Combat System? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Health and Combat System

When to Use

Use this skill when:

  • Implementing health and damage
  • Creating combat mechanics
  • Adding status effects
  • Building armor/defense systems
  • Implementing healing
  • Creating damage types

Core Principles

  1. Event-Driven: Use events for damage/healing
  2. Extensible: Support multiple damage types
  3. Balanced: Clear combat formulas
  4. Feedback: Visual/audio damage feedback
  5. Data-Driven: Configure via components
  6. Invulnerability: Temporary damage immunity

Health and Combat Implementation

1. Health Components

// components/Health.ts
export class Health {
  current: number;
  max: number;
  regenRate: number = 0; // HP per second
  isInvulnerable: boolean = false;
  invulnerabilityDuration: number = 0;

  constructor(max: number, current?: number, regenRate: number = 0) {
    this.max = max;
    this.current = current ?? max;
    this.regenRate = regenRate;
  }

  isDead(): boolean {
    return this.current = this.max;
  }

  getHealthPercent(): number {
    return this.current / this.max;
  }

  damage(amount: number): void {
    if (this.isInvulnerable) return;

    this.current = Math.max(0, this.current - amount);
  }

  heal(amount: number): void {
    this.current = Math.min(this.max, this.current + amount);
  }

  setInvulnerable(duration: number): void {
    this.isInvulnerable = true;
    this.invulnerabilityDuration = duration;
  }
}

// components/Armor.ts
export class Armor {
  value: number; // Flat damage reduction
  percentage: number = 0; // 0-1, percentage reduction

  constructor(value: number = 0, percentage: number = 0) {
    this.value = value;
    this.percentage = percentage;
  }

  calculateReduction(damage: number): number {
    // Apply percentage reduction first
    let reduced = damage * (1 - this.percentage);

    // Then flat reduction
    reduced = Math.max(0, reduced - this.value);

    return reduced;
  }
}

// components/Attack.ts
export class Attack {
  damage: number;
  damageType: string = 'physical';
  range: number;
  cooldown: number = 0;
  cooldownTime: number;
  attackSpeed: number = 1; // Attacks per second

  constructor(
    damage: number,
    range: number,
    cooldownTime: number = 1,
    damageType: string = 'physical'
  ) {
    this.damage = damage;
    this.range = range;
    this.cooldownTime = cooldownTime;
    this.damageType = damageType;
  }

  canAttack(): boolean {
    return this.cooldown  0;
  }

  shouldTick(): boolean {
    return this.timeSinceLastTick >= this.tickInterval;
  }

  tick(): void {
    this.timeSinceLastTick = 0;
  }

  addStack(): void {
    if (this.stacks ();

  add(effect: StatusEffect): void {
    const existing = this.effects.get(effect.type);

    if (existing) {
      // Refresh duration and add stack
      existing.remainingTime = Math.max(existing.remainingTime, effect.duration);
      existing.addStack();
    } else {
      this.effects.set(effect.type, effect);
    }
  }

  remove(type: StatusEffectType): void {
    this.effects.delete(type);
  }

  has(type: StatusEffectType): boolean {
    return this.effects.has(type);
  }

  get(type: StatusEffectType): StatusEffect | undefined {
    return this.effects.get(type);
  }

  getAll(): StatusEffect[] {
    return Array.from(this.effects.values());
  }

  clear(): void {
    this.effects.clear();
  }
}

3. Combat System

// systems/CombatSystem.ts
export class CombatSystem extends UpdateSystem {
  priority = 35;
  private eventBus: EventBus;

  constructor(eventBus: EventBus) {
    super();
    this.eventBus = eventBus;
  }

  update(world: World, deltaTime: number): void {
    // Update attack cooldowns
    this.updateCooldowns(world, deltaTime);

    // Update invulnerability
    this.updateInvulnerability(world, deltaTime);

    // Process attacks
    this.processAttacks(world);

    // Update status effects
    this.updateStatusEffects(world, deltaTime);

    // Health regeneration
    this.updateHealthRegen(world, deltaTime);

    // Check for deaths
    this.checkDeaths(world);
  }

  private updateCooldowns(world: World, deltaTime: number): void {
    const entities = world.query([Attack]);

    entities.iterate((entity, [attack]) => {
      if (attack.cooldown > 0) {
        attack.cooldown = Math.max(0, attack.cooldown - deltaTime);
      }
    });
  }

  private updateInvulnerability(world: World, deltaTime: number): void {
    const entities = world.query([Health]);

    entities.iterate((entity, [health]) => {
      if (health.isInvulnerable) {
        health.invulnerabilityDuration -= deltaTime;

        if (health.invulnerabilityDuration ([Transform, Attack]);
    const targets = world.query([Transform, Health]);

    attackers.iterate((attacker, [attackerTransform, attack]) => {
      if (!attack.canAttack()) return;

      // Find targets in range
      targets.iterate((target, [targetTransform, health]) => {
        if (target === attacker) return;

        const distance = attackerTransform.position.distanceTo(targetTransform.position);

        if (distance ([Health, StatusEffects]);

    entities.iterate((entity, [health, statusEffects]) => {
      const effects = statusEffects.getAll();

      for (const effect of effects) {
        // Update effect duration
        const stillActive = effect.update(deltaTime);

        if (!stillActive) {
          statusEffects.remove(effect.type);
          continue;
        }

        // Apply effect
        if (effect.shouldTick()) {
          this.applyStatusEffect(entity, health, effect);
          effect.tick();
        }
      }
    });
  }

  private applyStatusEffect(entity: Entity, health: Health, effect: StatusEffect): void {
    const value = effect.getEffectiveValue();

    switch (effect.type) {
      case StatusEffectType.Poison:
      case StatusEffectType.Burn:
        health.damage(value);
        break;

      case StatusEffectType.Regeneration:
        health.heal(value);
        break;

      case StatusEffectType.Stun:
        // Handled by movement/AI systems
        break;

      case StatusEffectType.Slow:
        // Handled by movement system
        break;
    }
  }

  private updateHealthRegen(world: World, deltaTime: number): void {
    const entities = world.query([Health]);

    entities.iterate((entity, [health]) => {
      if (health.regenRate > 0 && !health.isFullHealth()) {
        health.heal(health.regenRate * deltaTime);
      }
    });
  }

  private checkDeaths(world: World): void {
    const entities = world.query([Health]);

    entities.iterate((entity, [health]) => {
      if (health.isDead() && entity.active) {
        this.eventBus.emit(new DeathEvent(entity, null));
        entity.active = false;
      }
    });
  }
}

4. Damage Types System

// combat/DamageTypeSystem.ts
export interface DamageResistance {
  physical: number; // 0-1 (0 = immune, 1 = full damage)
  fire: number;
  ice: number;
  poison: number;
  lightning: number;
}

export class DamageResistances {
  resistances: DamageResistance = {
    physical: 1,
    fire: 1,
    ice: 1,
    poison: 1,
    lightning: 1,
  };

  getResistance(damageType: string): number {
    return this.resistances[damageType as keyof DamageResistance] ?? 1;
  }

  setResistance(damageType: string, value: number): void {
    if (damageType in this.resistances) {
      this.resistances[damageType as keyof DamageResistance] = Math.max(0, Math.min(1, value));
    }
  }

  calculateDamage(baseDamage: number, damageType: string): number {
    return baseDamage * this.getResistance(damageType);
  }
}

Usage Examples

// Example 1: Basic combat setup
const player = world.createEntity();
player.addComponent(new Health(100, 100, 5)); // 100 HP, 5 HP/s regen
player.addComponent(new Armor(10, 0.2)); // 10 flat reduction, 20% reduction
player.addComponent(new Attack(15, 2, 0.5)); // 15 damage, 2 range, 0.5s cooldown

const enemy = world.createEntity();
enemy.addComponent(new Health(50));
enemy.addComponent(new Attack(10, 1.5, 1));

// Example 2: Apply status effect
const statusEffects = entity.getComponent(StatusEffects) ||
  entity.addComponent(new StatusEffects());

// Apply poison
statusEffects.add(new StatusEffect({
  type: StatusEffectType.Poison,
  duration: 5,
  tickInterval: 1,
  value: 2, // 2 damage per second
}));

// Apply regeneration
statusEffects.add(new StatusEffect({
  type: StatusEffectType.Regeneration,
  duration: 10,
  tickInterval: 1,
  value: 5, // 5 HP per second
}));

// Example 3: Damage resistances
const resistances = enemy.addComponent(new DamageResistances());
resistances.setResistance('fire', 0.5); // 50% fire resistance
resistances.setResistance('ice', 1.5); // 150% ice damage (weakness)
resistances.setResistance('physical', 0); // Immune to physical

// Example 4: Healing potion
function useHealthPotion(entity: Entity): void {
  const health = entity.getComponent(Health);
  if (health) {
    health.heal(50);
    eventBus.emit(new HealEvent(entity, 50));
  }
}

// Example 5: Critical hits
class CriticalHitSystem extends UpdateSystem {
  private critChance = 0.2; // 20%
  private critMultiplier = 2;

  update(world: World, deltaTime: number): void {
    // Listen to damage events
    eventBus.on(DamageEvent, (event) => {
      if (Math.random() ();
  private comboWindow = 2; // 2 seconds

  update(world: World, deltaTime: number): void {
    eventBus.on(DamageEvent, (event) => {
      if (!event.source) return;

      const now = performance.now() / 1000;
      const combo = this.combos.get(event.source) ?? { count: 0, lastHitTime: 0 };

      // Check if within combo window
      if (now - combo.lastHitTime  1) {
        const multiplier = 1 + (combo.count - 1) * 0.1; // +10% per combo
        const bonusDamage = event.amount * (multiplier - 1);
        const health = event.target.getComponent(Health);
        if (health) {
          health.damage(bonusDamage);
        }
      }
    });
  }
}

// Example 7: Lifesteal
class LifestealSystem extends UpdateSystem {
  private lifestealPercent = 0.2; // 20%

  update(world: World, deltaTime: number): void {
    eventBus.on(DamageEvent, (event) => {
      if (!event.source) return;

      const sourceHealth = event.source.getComponent(Health);
      if (sourceHealth) {
        const healAmount = event.amount * this.lifestealPercent;
        sourceHealth.heal(healAmount);
      }
    });
  }
}

Checklist

  • [ ] Add Health components
  • [ ] Implement Attack components
  • [ ] Create combat system
  • [ ] Add armor/resistance system
  • [ ] Implement status effects
  • [ ] Add healing mechanics
  • [ ] Create damage events
  • [ ] Add visual feedback
  • [ ] Test combat balance
  • [ ] Profile performance

Common Pitfalls

  1. No invulnerability: Hit multiple times per frame
  2. Wrong damage calculation: Armor broken
  3. No death check: Entities with negative HP
  4. Forgotten cooldowns: Instant attacks
  5. Status effect stacking: Unlimited stacks
  6. No resistance system: All damage same
  7. Missing events: No damage feedback

Performance Tips

Combat Optimization

  • Update cooldowns once per frame
  • Cache damage calculations
  • Limit status effect checks
  • Use spatial queries for range checks
  • Batch damage events

Memory Optimization

  • Pool damage events
  • Reuse status effect objects
  • Limit active status effects
  • Clear expired effects immediately

Mobile Considerations

  • Simpler damage calculations
  • Fewer status effects
  • Lower tick rates for DoT
  • Simpler resistance system
  • Fewer damage types

Related Skills

  • ecs-events - Combat events
  • ecs-system-patterns - System implementation
  • audio-system - Combat sounds
  • ui-system - Health bars
  • collision-system - Hit detection

References

  • Combat system design
  • Damage calculation formulas
  • Status effect patterns
  • RPG mechanics design

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.