Tesla line
What it is
A tesla line is a shared weapon behavior that spawns two energy balls travelling forward together while drifting apart perpendicular to the fire direction. The damage hitbox is the line segment connecting the two balls — any enemy whose body overlaps that segment takes a tick of damage, gated by a per-enemy contact cooldown. It is the geometry behind the energy-family premium weapons that read as a stretched electric tether sweeping across the battlefield.
Geometry
The behavior locks a fire direction at spawn and then drives two balls outward from that axis on each frame.
| Step | What the behavior does |
|---|---|
| 1 | Lock a forward angle from the ship’s aim at spawn; this angle never changes for the life of the bullet |
| 2 | Move the bullet’s midpoint forward along the locked angle at the configured forward speed |
| 3 | Each frame, advance a perpendicular spread offset by the spread speed, capped at the maximum spread |
| 4 | Place ball 1 at midpoint + perpendicular × spread and ball 2 at midpoint − perpendicular × spread |
| 5 | Inflate the bullet’s collision radius to cover the full ball-to-ball distance so the spatial grid still returns nearby enemies |
| 6 | Emit spark particles at random points along the segment for the electric-arc visual |
| 7 | On bullet expiry, burst spark particles at both ball positions |
The perpendicular axis is the 90° CCW rotation of the forward axis, so the two balls always fly to the left-hand and right-hand sides of the firing direction. The maximum spread is the orbit-radius stat; the spread speed is the orbit-speed stat. The behavior caches the per-frame ball positions on the bullet so the collision resolver can read them directly.
| Quantity | Source |
|---|---|
| Forward axis | Locked at spawn from ship aim |
| Perpendicular axis | 90° CCW of forward axis |
| Forward speed (px/s) | Projectile-speed stat |
| Spread speed (px/s) | Orbit-speed stat |
| Maximum spread per ball (px) | Orbit-radius stat |
| Ball-to-ball segment length (px) | Twice the current spread |
Hit resolution
A dedicated collision routine fires every frame the bullet is alive. It treats the ball-to-ball line as a thick segment and damages any enemy whose body overlaps it.
| Step | What the resolver does |
|---|---|
| 1 | Read the two cached ball positions from the bullet |
| 2 | Bail out if the segment is degenerate (length below 1 px) |
| 3 | Query the spatial grid for enemies near the segment midpoint with a radius of segment length / 2 + thickness + 30 |
| 4 | For each candidate, project the enemy centre onto the segment and clamp the projection to the segment endpoints |
| 5 | Compute the distance from the enemy centre to that nearest point on the segment |
| 6 | If the distance is below line thickness + enemy collision radius and the enemy is not on per-enemy cooldown, damage the enemy and start a fresh cooldown entry |
| 7 | Spawn a spark burst at the impact point and run the standard impact-VFX hook |
Newly-spawned enemies are skipped while their spawn timer is still under the global spawn-immunity window. Enemies frozen for lag-pause handling are also skipped. The bullet’s per-enemy cooldown map is initialised on first frame and survives until the bullet is recycled.
| Quantity | Value |
|---|---|
| Default line thickness (px) | 6 |
| Default per-enemy contact cooldown (seconds) | 0.3 |
| Spawn-immunity skip window (seconds) | 0.15 |
| Spatial-grid query buffer beyond half-segment (px) | thickness + 30 |
| Sparks per impact burst | 3 |
| Impact-spark colour | Bullet’s primary colour |
Both tesla-line weapons override the default cooldown to 0.08 s, so each enemy can take up to ~12 ticks per second while a segment hovers across it.
Which weapons use it
Two epic energy weapons share the tesla-line behavior; their stats diverge but the geometry and hit resolution are identical.
| Weapon | Family | Damage tag | Collision mode | Per-enemy cooldown (seconds) |
|---|---|---|---|---|
| Line | Projectile | Energy | Pierce all | 0.08 |
| Magnetar | Projectile | Energy | Pierce all | 0.08 |
Both weapons aim at the closest enemy, can hit destructibles, and use the line-spread area mode for the in-game range indicator.
| Stat | Line (L1) | Line (L20) | Magnetar (L1) | Magnetar (L20) |
|---|---|---|---|---|
| Damage per tick | 31.2 | 131.80 | 42.0 | 152.2 |
| Fire rate (shots/s) | 0.20 | 0.667 | 0.15 | 0.53 |
| Projectile speed (px/s) | 120 | 177 | 100 | 147.5 |
| Projectile size (px) | 14 | 25.4 | 18 | 31.3 |
| Maximum spread per ball (px) | 55 | 170 | 85 | 237 |
| Spread speed (px/s) | 30 | 45.2 | 25 | 38.3 |
| Acquire range (px) | 220 | 296 | 350 | 464 |
| Travel-range multiplier | 3.0 | 3.0 | 5.0 | 5.0 |
| Warmup (seconds) | 0 | 0 | 0.10 | 0.10 |
Line reads as a quick electric-blue strike with a tight initial spread. Magnetar reads as a heavier violet-magenta tether: slower fire rate and slower spin but wider final spread, longer travel range, longer acquire range, and a brief warmup before the first cast.
EXTRACT-CANDIDATEs
- EXTRACT-CANDIDATE: spawn-immunity window — the global
_spawnT > 0.15skip used by every contact-cooldown collision routine; deserves its own concept page so per-weapon docs stop redescribing it. - EXTRACT-CANDIDATE: lag-pause
_frozenForLagenemy flag — a global skip used by tesla-line, cone-beam-dot, and other DOT-style resolvers; pair with the spawn-immunity page. - EXTRACT-CANDIDATE: spatial-grid candidate-list fallback (
candidates.length > 0 ? candidates : enemies) — a recurring resolver pattern that handles unit-test paths which bypass the grid; useful for the combat page. - EXTRACT-CANDIDATE: point-to-line-segment distance helper (project onto segment, clamp to endpoints, hypot to nearest point) — re-implemented inline in this resolver and could become a shared geometry primitive shared with future tether weapons.
- EXTRACT-CANDIDATE: bullet-radius inflation for spread weapons (
b.rad = max(ballRadius, spread + 10)) — a workaround so the spatial grid still returns nearby enemies once the visible hitbox is wider than the underlying bullet entity; relevant for any future two-body weapon. - EXTRACT-CANDIDATE: impact-spark colour derived from
b.c1hex slice — the resolver parses the bullet’s primary hex colour into RGB inline; a shared “bullet colour → RGB” helper would let other resolvers stop repeating the slice math.