logo

Babylon.js Market

SpaceShooterHealth

shooter · space-combat-sim

SpaceShooterHealth

1
Unlock

Install with the CLI:

bjs download SpaceShooterHealth

SpaceShooterHealth

The one kill path a 6-DOF space-shooter funnels every death through: destroyShip blows a ship apart — explosion, part detach, shootable debris, respawn — and the aggregate hit-point bucket the HUD bar reads.

What it does

SpaceShooterHealthComponent is pure data: hp / maxHp. For a multi-part ship it is derived — the bullet-impact pass recomputes hp = Parts.totalHp() after every hit, so the aggregate bar tracks per-part damage; the real kill decision is made per-part (a critical part reaching 0), not off this number. For a simple single-box target like floating debris it stands alone. It has no per-frame System of its own; what lives here is the destruction logic every damage source shares.

destroyShip(world, eventBus, ship) is that shared path. It first emits SpaceShooterHealthEvents.EXPLOSION at the ship's pose (the burst-FX origin). Then it forks on who died:

  • An enemy sheds its hull. For every still-attached Parts piece it emits wingman.part.destroyed (the renderer detaches that child mesh) and acquires a pooled, still-shootable debris hitbox at the piece's world position — so the wreckage keeps taking fire. Then it emits wingman.enemy.killed (or wingman.freighter.killed for a convoy head, wingman.freighter.car.lost for a cargo car) and removes the ship.
  • The player does a respawn-in-place death instead: it emits wingman.player.killed, hides the model (Renderable.visible = false), blows the primitives apart (wingman.player.blownapart), zeroes velocity, stops the guns, tags the ship dead, and attaches a RespawnTimer. No part-detach — there's no re-attach path, so a respawning player would otherwise stay invisible.

A ship already tagged dead is ignored, so a second hit mid-respawn can't double-explode it or reset the timer.

spawnDebrisHitbox(world, …) acquires one slot from the shared debris pool at a shed part's location and seeds a tumbling trajectory that inherits the dead ship's motion. The pool is a Debris blueprint entity in the scene (a Pool marker beside Transform6DOF + Velocity6DOF + SpaceShooterHealth(1) + Lifetime, tagged debris-shootable) — so no impact system registers it by hand; the pool's 1 HP + 6-second clock are re-applied on each acquire.

Use it in a scene

You don't key SpaceShooterHealth on an entity — the death path is imported by the impact components, and ships carry their aggregate HP via ShipLoadout. It becomes part of a scene implicitly: pull any of MachineGun / Missile / Asteroid / OilBlob and this rides along as a dependency. A ship that should be able to die needs Transform6DOF + Parts (and, if it's the player, Renderable + MachineGun) so destroyShip has something to detach and hide.

Events

  • Emits wingman.explosion (SpaceShooterHealthEvents.EXPLOSION) at every death — { x, y, z, vx, vy, vz }. The burst-FX origin; the visual is the renderer's job.
  • Emits wingman.part.destroyed (PartsEvents.DESTROYED) once per detached enemy piece — { entityId, part, x, y, z, meshSuffixes }. Drives the renderer's child-mesh detach and seeds a debris hitbox.
  • Emits wingman.player.killed / wingman.player.blownapart for the player death sequence, and wingman.enemy.killed / wingman.freighter.killed / wingman.freighter.car.lost for the three non-player death classes. MissionDirector, WaveDirector and SpaceShooterScore listen for these.
  • Listens for nothing — destroyShip is called imperatively by the impact systems, not driven off the bus.

Dependencies

  • Transform6DOF / Velocity6DOF — the ship's pose + motion, read to place the explosion and seed debris trajectories; also the pooled debris entities' own motion.
  • Parts — the per-piece hull; destroyShip walks Parts.defs, emits a detach per surviving piece, and spawns a debris hitbox at each.
  • Renderable — flipped invisible on the player's death (the one renderer touch).
  • MachineGun — the player's guns, silenced (isFiring = false) on death so a dead ship can't keep shooting.
  • RespawnTimer — attached to the player on death to drive the respawn-in-place countdown.
  • Lifetime — every pooled debris hitbox carries one so wreckage self-expires after 6s.

Notes

  • The death event names live in the shared arcade dictionary, not in this component — SpaceShooterHealthEvents sits in @babylonjsmarket/arcade alongside WaypointEvents. Emitters (this) and listeners (MissionDirector / WaveDirector / SpaceShooterScore) both import the names from there, so no listener imports this file (the no-cross-component-event-import contract).
  • destroyShip never reads the ship's SpaceShooterHealthComponent. The decision to call it is made upstream (a critical part hit 0, or an instant-kill hazard); this path is purely the consequence of death. The component only travels on the pooled debris, where 1 HP makes each piece a one-shot target.
  • removeEntity on an enemy is a real removal; on a pooled attacker (a debris slot, a missile) upstream systems release the slot instead. destroyShip itself only ever removeEntitys the ship that died.

More like this

Lifetime
MachineGun
MissionDirector
Parts
Renderable
RespawnTimer
SpaceShooterScore
Transform6DOF
Velocity6DOF
WaveDirector
AiPilot
Animation
ArcCamera
Asteroid
Bullet
CameraFollow
ChaseCamera6DOF
ChaseCameraTarget
DirectionalLight
Enemy
EnemySpawner
EnvironmentTexture
FlightIntent
FreighterCar
FreighterChain
FreighterHead
GameConfig
Health
HealthBar
HemisphericLight
Jump
KeyboardInput
KeyboardMover
LineOfSight
Mesh
MeshPrimitive
Missile
MissileLauncher
MoneyField
Movement
Obstacle
ObstacleField
OilBlob
Physics
PlayerFlightInput
PlayerInput
PlayerWalkAnimator
Score
Shadow
ShipFlight
ShipLoadout
ShooterCamera
SkeletonAnimator
SpaceDust
SpaceShooterBullet
TwinStickShooter
Waypoint
WaypointTrack
WorldOriginAnchor

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search