Skip to main content

Projectile Component

ProjectileComponent marks an entity as a projectile and stores its damage value and the entity that fired it.

ProjectileComponent

struct ProjectileComponent: Component {
var damage: Float
var owner: Entity
}
PropertyTypeDescription
damageFloatHit-point damage dealt on impact
ownerEntityThe entity that fired this projectile (used to avoid self-damage)

Creating a Projectile Entity

Projectiles are created via EntityFactory.makeProjectile:

EntityFactory.makeProjectile(
from: ownerTransform.position,
aimAt: fireDirection,
speed: speedWhenFired,
owner: ownerEntity,
in: world
)

These components attache to the new entity (the projectile):

ComponentValue
TransformComponentSpawns at the given position; rotation derived from direction
VelocityComponentdirection * speed
SpriteComponent"normalHandgunBullet", z-position 5
ProjectileComponentdamage in factory method: 10, owner: ownerEntity
EffectiveRangeComponentbase in factory method: 400 units
CollisionBoxComponent6 × 6 point hitbox

Lifetime

A projectile is destroyed when either:

  1. Range is exhaustedEffectiveRangeComponent.value.current reaches 0 (base range: 400 units).
  2. It hits a solid — the CollisionEventBuffer emits a projectileHitSolid event for it.

Both cases enqueue the entity in DestructionQueue, which flushes at the end of ProjectileSystem.update.

In future iterations, we want to add a third case for hitting a damageable entity (e.g. an enemy), but currently projectiles pass through enemies without collision.

ProjectileSystem

ProjectileSystem runs at priority: 60 — after WeaponSystem (priority 50) so any newly spawned projectiles are already in the world when movement is applied.

Each frame it:

  1. Moves every projectile by velocity × deltaTime.
  2. Decrements EffectiveRangeComponent by the distance traveled; enqueues expired projectiles.
  3. Reads CollisionEventBuffer.projectileHitSolid and enqueues all hit projectiles.
  4. Flushes DestructionQueue.

Dependencies

DependencyRole
VelocityComponentStores the projectile's linear velocity vector
EffectiveRangeComponentTracks remaining travel distance before auto-destruction
CollisionBoxComponentDefines the hitbox for wall/solid collision detection
CollisionEventBufferSource of projectileHitSolid events
DestructionQueueDeferred entity removal to avoid mutating the world mid-iteration
EntityFactoryFactory method for creating projectile entities