From 17a380f85fd7c4f5db9e3442317811686924e29f Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:12:29 -0400
Subject: [PATCH 01/14] Tesla passive energy decay: ball starves without a
running PA
The ball bleeds 10 energy/s, pinned to the Level-1 PA feed rate
(3 emitters * 20 energy / 6s wave), so Level 1 is exactly break-even:
alive, no motes. Standby/Level 0 starves it into collapse, Level 2+
nets positive. Despawn floor deepened to -600 (~60s starvation grace)
because feed lands in 6-second lumps and the stock -100 floor would
kill the ball after barely two missed waves.
Decay defaults to 0 on the component so other users are unaffected;
the tesla prototype opts in.
---
.../Tesla/Components/TeslaEnergyBallComponent.cs | 8 ++++++++
.../Tesla/EntitySystem/TeslaEnergyBallSystem.cs | 16 ++++++++++++++++
.../Power/Generation/Tesla/energyball.yml | 6 ++++++
3 files changed, 30 insertions(+)
diff --git a/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs b/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
index 5e1c62f3042..1f65f8c5428 100644
--- a/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
+++ b/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
@@ -34,6 +34,14 @@ public sealed partial class TeslaEnergyBallComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float EnergyToDespawn = -100f;
+ ///
+ /// Triad: energy bled passively per second while the ball exists. 0 disables decay (upstream
+ /// behavior, the default). The tesla prototype pins this to the Level-1 PA feed rate so Level 1
+ /// is break-even: alive, no motes. See energyball.yml.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float PassiveEnergyDecay;
+
///
/// Played when energy reaches the lower limit (and entity destroyed)
///
diff --git a/Content.Server/Tesla/EntitySystem/TeslaEnergyBallSystem.cs b/Content.Server/Tesla/EntitySystem/TeslaEnergyBallSystem.cs
index 606f4615af3..f1a5668b73f 100644
--- a/Content.Server/Tesla/EntitySystem/TeslaEnergyBallSystem.cs
+++ b/Content.Server/Tesla/EntitySystem/TeslaEnergyBallSystem.cs
@@ -26,6 +26,22 @@ public override void Initialize()
SubscribeLocalEvent(OnConsumed);
}
+ // Triad: passive energy decay. The ball bleeds energy continuously so it needs a running PA to
+ // sustain it; with no feed it drains to EnergyToDespawn and collapses.
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var teslaEnergyBall))
+ {
+ if (teslaEnergyBall.PassiveEnergyDecay <= 0f)
+ continue;
+
+ AdjustEnergy(uid, teslaEnergyBall, -teslaEnergyBall.PassiveEnergyDecay * frameTime);
+ }
+ }
+
private void OnConsumed(Entity tesla, ref EntityConsumedByEventHorizonEvent args)
{
Spawn(tesla.Comp.ConsumeEffectProto, Transform(args.Entity).Coordinates);
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
index 43fce933263..cc2c34b4077 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
@@ -73,6 +73,12 @@
consumeEntities: false
- type: TeslaEnergyBall
spawnProto: TeslaMiniEnergyBall
+ # Triad: wild-tesla economy. Decay pinned to the Level-1 PA feed (3 emitters * 20 energy / 6s = 10/s)
+ # so Level 1 is break-even (alive, no motes), Standby/Level 0 starves the ball, Level 2+ makes motes.
+ # The deep despawn floor gives ~60s of grace under full starvation before collapse, since feed lands
+ # in 6-second lumps and the stock -100 floor would kill it after barely two missed waves.
+ passiveEnergyDecay: 10
+ energyToDespawn: -600
soundCollapse:
path: /Audio/Effects/tesla_collapse.ogg
params:
From a02094d308e48528926dc9563ecf8b6b63066b36 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:13:18 -0400
Subject: [PATCH 02/14] Tesla mote count tuned to the PA regime ladder
With decay in place the threshold mechanism already scales mote output
with net feed: spawn rate = net feed / needEnergyToSpawn, and motes
live 120s. Threshold 120 lands the ladder at Level 1 = 0 motes,
Level 2 = 5, Level 3 = 20 sustained.
---
.../Entities/Structures/Power/Generation/Tesla/energyball.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
index cc2c34b4077..71b455cd85c 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
@@ -79,6 +79,9 @@
# in 6-second lumps and the stock -100 floor would kill it after barely two missed waves.
passiveEnergyDecay: 10
energyToDespawn: -600
+ # Mote count self-regulates: spawn rate = net feed / needEnergyToSpawn, motes live 120s, so
+ # Level 3 (net +20/s) sustains 20*120/120 = 20 motes and Level 2 (net +5/s) sustains 5.
+ needEnergyToSpawn: 120
soundCollapse:
path: /Audio/Effects/tesla_collapse.ogg
params:
From 6cb861808fb1726e0b6175c9697a6213fe9e33f6 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:16:19 -0400
Subject: [PATCH 03/14] Charge-aware lightning routing: coils bid by headroom
New LightningStrikeAttemptEvent raised on each candidate before a
volley is sorted and rolled, letting targets adjust their effective
priority and hit chance from live state. Targets with no subscriber
keep their static values.
Tesla coils subscribe: an empty coil is a guaranteed catch with a
priority bump above every charged coil, and chance scales down with
charge to a 0.05 floor when full, so overflow falls through to the
grounding rods. At half charge the effective chance is ~0.52, close
to the old static 0.5.
---
Content.Server/Lightning/LightningSystem.cs | 40 +++++++++++++++----
.../Tesla/Components/TeslaCoilComponent.cs | 17 ++++++++
.../Tesla/EntitySystem/TeslaCoilSystem.cs | 20 ++++++++++
.../Power/Generation/Tesla/coil.yml | 2 +-
4 files changed, 70 insertions(+), 9 deletions(-)
diff --git a/Content.Server/Lightning/LightningSystem.cs b/Content.Server/Lightning/LightningSystem.cs
index c3bc6c257b0..55d38ac7ea0 100644
--- a/Content.Server/Lightning/LightningSystem.cs
+++ b/Content.Server/Lightning/LightningSystem.cs
@@ -106,8 +106,20 @@ private void ShootRandomLightnings(EntityUid user, float range, int boltCount, E
// several hashsets every time
var targets = _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(user), range).ToList();
- _random.Shuffle(targets);
- targets.Sort((x, y) => y.Comp.Priority.CompareTo(x.Comp.Priority));
+ // Triad: strike-attempt hook. Each candidate may adjust its effective priority and hit chance
+ // from live state (tesla coils bid by charge headroom) before the volley is sorted and rolled.
+ // Targets with no subscriber keep their static values, so behavior is unchanged for them.
+ // _random.Shuffle(targets);
+ // targets.Sort((x, y) => y.Comp.Priority.CompareTo(x.Comp.Priority));
+ var candidates = new List<(Entity Target, int Priority, float HitProbability)>(targets.Count);
+ foreach (var target in targets)
+ {
+ var attempt = new LightningStrikeAttemptEvent(user, target.Comp.Priority, target.Comp.HitProbability);
+ RaiseLocalEvent(target, ref attempt);
+ candidates.Add((target, attempt.Priority, Math.Clamp(attempt.HitProbability, 0f, 1f)));
+ }
+ _random.Shuffle(candidates);
+ candidates.Sort((x, y) => y.Priority.CompareTo(x.Priority));
int shootedCount = 0;
int count = -1;
@@ -115,16 +127,16 @@ private void ShootRandomLightnings(EntityUid user, float range, int boltCount, E
{
count++;
- if (count >= targets.Count) { break; }
+ if (count >= candidates.Count) { break; }
- var curTarget = targets[count];
- if (!_random.Prob(curTarget.Comp.HitProbability)) //Chance to ignore target
+ var curTarget = candidates[count];
+ if (!_random.Prob(curTarget.HitProbability)) //Chance to ignore target
continue;
- ShootLightning(user, targets[count].Owner, spawnOnHit, lightningPrototype, triggerLightningEvents);
- if (arcDepth - targets[count].Comp.LightningResistance > 0)
+ ShootLightning(user, curTarget.Target.Owner, spawnOnHit, lightningPrototype, triggerLightningEvents);
+ if (arcDepth - curTarget.Target.Comp.LightningResistance > 0)
{
- ShootRandomLightnings(targets[count].Owner, range, 1, spawnOnHit, lightningPrototype, arcDepth - targets[count].Comp.LightningResistance, triggerLightningEvents);
+ ShootRandomLightnings(curTarget.Target.Owner, range, 1, spawnOnHit, lightningPrototype, arcDepth - curTarget.Target.Comp.LightningResistance, triggerLightningEvents);
}
shootedCount++;
}
@@ -138,3 +150,15 @@ private void ShootRandomLightnings(EntityUid user, float range, int boltCount, E
/// The entity that was struck by lightning.
[ByRefEvent]
public readonly record struct HitByLightningEvent(EntityUid Source, EntityUid Target);
+
+///
+/// Triad: raised directed on each candidate target before a lightning volley is sorted and rolled.
+/// Subscribers may adjust and from live state
+/// (e.g. a tesla coil bidding by charge headroom). Both start at the target's static
+/// LightningTargetComponent values; HitProbability is clamped to [0, 1] after the event.
+///
+/// The entity shooting the lightning volley
+/// Effective sort priority for this volley; higher is struck first
+/// Effective chance this target is not skipped by the roll
+[ByRefEvent]
+public record struct LightningStrikeAttemptEvent(EntityUid Source, int Priority, float HitProbability);
diff --git a/Content.Server/Tesla/Components/TeslaCoilComponent.cs b/Content.Server/Tesla/Components/TeslaCoilComponent.cs
index d9c7be6fe4d..1ba42efbd4d 100644
--- a/Content.Server/Tesla/Components/TeslaCoilComponent.cs
+++ b/Content.Server/Tesla/Components/TeslaCoilComponent.cs
@@ -14,4 +14,21 @@ public sealed partial class TeslaCoilComponent : Component
// To Do: Different lightning bolts have different powers and generate different amounts of energy
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float ChargeFromLightning = 50000f;
+
+ ///
+ /// Triad: strike-chance floor once the battery is full. Lightning favors the biggest potential
+ /// difference, so the coil's effective hit chance scales with charge headroom: empty = 1.0
+ /// (plus a priority bump above every static target), full = this floor. A floored coil still
+ /// outranks grounding rods in the sort but gets skipped on almost every roll, so overflow
+ /// falls through to the rods.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float SaturatedHitProbability = 0.05f;
+
+ ///
+ /// Triad: priority added on top of the coil's static LightningTarget priority while the battery
+ /// is completely empty, so a fresh coil catches the next bolt ahead of every charged coil.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int EmptyPriorityBonus = 1;
}
diff --git a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
index 4fd2f9b6ed0..5dd01832798 100644
--- a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
+++ b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
@@ -17,6 +17,7 @@ public override void Initialize()
base.Initialize();
SubscribeLocalEvent(OnHitByLightning);
+ SubscribeLocalEvent(OnLightningStrikeAttempt); // Triad
}
//When struck by lightning, charge the internal battery
@@ -27,4 +28,23 @@ private void OnHitByLightning(Entity coil, ref HitByLightnin
_battery.SetCharge(coil, batteryComponent.CurrentCharge + coil.Comp.ChargeFromLightning);
}
}
+
+ // Triad: bid for the strike by charge headroom. An empty coil is a guaranteed catch and outbids
+ // every static target; a full coil floors at SaturatedHitProbability so bolts fall through to
+ // the grounding rods. At half charge the effective chance is ~0.52, close to the old static 0.5.
+ private void OnLightningStrikeAttempt(Entity coil, ref LightningStrikeAttemptEvent args)
+ {
+ if (!TryComp(coil, out var battery) || battery.MaxCharge <= 0f)
+ return;
+
+ if (battery.CurrentCharge <= 0f)
+ {
+ args.Priority += coil.Comp.EmptyPriorityBonus;
+ args.HitProbability = 1f;
+ return;
+ }
+
+ var headroom = 1f - battery.CurrentCharge / battery.MaxCharge;
+ args.HitProbability = MathHelper.Lerp(coil.Comp.SaturatedHitProbability, 1f, headroom);
+ }
}
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index fbb1d8c1b0b..6756c502653 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -63,7 +63,7 @@
chargeFromLightning: 2000000
- type: LightningTarget
priority: 4
- hitProbability: 0.5
+ hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
lightningResistance: 10
lightningExplode: false
- type: PowerNetworkBattery
From ed419e24ffcd092f8acb306832d7115ec5499e41 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:18:30 -0400
Subject: [PATCH 04/14] Saturated tesla coils hold the arcing indicator
New TeslaCoilVisuals.Charged appearance key driven off
ChargeChangedEvent: while the battery cannot bank a full strike the
coil shows the existing arc sprite on its own layer, so the 4-second
strike flash cannot clobber it. Clears on its own as the coil pushes
charge into the grid.
---
Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs | 11 +++++++++++
Content.Shared/Power/TeslaCoilVisuals.cs | 3 ++-
.../Structures/Power/Generation/Tesla/coil.yml | 7 +++++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
index 5dd01832798..08abd3f9a38 100644
--- a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
+++ b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs
@@ -2,6 +2,7 @@
using Content.Server.Power.EntitySystems;
using Content.Server.Tesla.Components;
using Content.Server.Lightning;
+using Content.Shared.Power; // Triad
namespace Content.Server.Tesla.EntitySystems;
@@ -11,6 +12,7 @@ namespace Content.Server.Tesla.EntitySystems;
public sealed class TeslaCoilSystem : EntitySystem
{
[Dependency] private readonly BatterySystem _battery = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!; // Triad
public override void Initialize()
{
@@ -18,6 +20,7 @@ public override void Initialize()
SubscribeLocalEvent(OnHitByLightning);
SubscribeLocalEvent(OnLightningStrikeAttempt); // Triad
+ SubscribeLocalEvent(OnChargeChanged); // Triad
}
//When struck by lightning, charge the internal battery
@@ -47,4 +50,12 @@ private void OnLightningStrikeAttempt(Entity coil, ref Light
var headroom = 1f - battery.CurrentCharge / battery.MaxCharge;
args.HitProbability = MathHelper.Lerp(coil.Comp.SaturatedHitProbability, 1f, headroom);
}
+
+ // Triad: hold the arcing indicator while the coil can't bank a full strike, so engineers can see
+ // saturation at a glance. Drains through the power net raise ChargeChangedEvent too, so the
+ // indicator clears on its own as the coil pushes charge into the grid.
+ private void OnChargeChanged(Entity coil, ref ChargeChangedEvent args)
+ {
+ _appearance.SetData(coil, TeslaCoilVisuals.Charged, args.Charge + coil.Comp.ChargeFromLightning > args.MaxCharge);
+ }
}
diff --git a/Content.Shared/Power/TeslaCoilVisuals.cs b/Content.Shared/Power/TeslaCoilVisuals.cs
index 2cc633f8604..27f56cef554 100644
--- a/Content.Shared/Power/TeslaCoilVisuals.cs
+++ b/Content.Shared/Power/TeslaCoilVisuals.cs
@@ -6,5 +6,6 @@ namespace Content.Shared.Power;
public enum TeslaCoilVisuals : byte
{
Enabled,
- Lightning
+ Lightning,
+ Charged // Triad: coil battery too full to accept a full strike; shows the persistent arcing indicator
}
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index 6756c502653..af8f07ef25d 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -30,6 +30,9 @@
- state: coilhit
visible: false
map: ["hit"]
+ - state: coilhit # Triad: persistent arc while saturated; own layer so the strike flash can't clobber it
+ visible: false
+ map: ["charged"]
- type: Appearance
- type: GenericVisualizer
visuals:
@@ -41,6 +44,10 @@
hit:
True: { visible: true }
False: { visible: false }
+ enum.TeslaCoilVisuals.Charged: # Triad
+ charged:
+ True: { visible: true }
+ False: { visible: false }
- type: LightningSparking
- type: AnimationPlayer
- type: NodeContainer
From 16ae0eecfcc0f2f9f93a7b5926a16e735e8f6a52 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:19:54 -0400
Subject: [PATCH 05/14] Re-proportion tesla coil economy and durability for
9-hour rounds
A strike now banks maxCharge/6 (500k into a 3M bank) instead of 2M
into a 1M bank, so the charge-headroom routing has a real gradient
and the saturation indicator means something. Coil supply cap is
unchanged at 1MW.
Strike damage drops 1 -> 0.05: ~4500 strikes to destruction, about
7 hours per coil at a moderate PA level under the mote-heavy strike
economy. Service intervals stretch by welding or adding coils.
---
.../Structures/Power/Generation/Tesla/coil.yml | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index af8f07ef25d..609f0cc2395 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -63,16 +63,22 @@
sprite: Structures/Power/Generation/Tesla/coil.rsi
state: coil
- type: Battery
- maxCharge: 1000000
+ # Triad: wild-tesla economy. A strike banks maxCharge/6, so the charge-headroom routing has a
+ # real gradient instead of one strike pegging the coil (upstream: 2M strike into a 1M bank).
+ maxCharge: 3000000
startingCharge: 0
- type: BatteryDischarger
- type: TeslaCoil
- chargeFromLightning: 2000000
+ chargeFromLightning: 500000 # Triad: was 2000000, see Battery note
- type: LightningTarget
priority: 4
hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
lightningResistance: 10
lightningExplode: false
+ # Triad: durability for 9-hour rounds under the mote-heavy strike economy: ~4500 strikes to
+ # destruction (~7h at a moderate PA level per coil). Stretch service intervals by welding
+ # (Repairable) or spreading load across more coils.
+ damageFromLightning: 0.05
- type: PowerNetworkBattery
maxSupply: 1000000
supplyRampTolerance: 1000000
From 47ebff068ef12fbf726f319372c4ceadd3105cb6 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:33:30 -0400
Subject: [PATCH 06/14] Lightning strikes electrocute mobs instead of doing
nothing
Mobs have been on the strike table (priority 1) since the Mono port
but took zero damage: the strike applies Structural, which no-ops on
Biological damage containers. LightningTarget gains an opt-in
electrocution path (15 shock, 5s, insulated gloves apply) enabled on
the mob base, so bolts that overflow the coils and rods now zap
whoever they land on. Mob lightningResistance stays 1, so a bolt can
arc once more onward from the victim.
Note this applies to every ShootRandomLightnings source, including
the electrical anomaly, not just the tesla.
---
.../Components/LightningTargetComponent.cs | 22 +++++++++++++++++++
.../Lightning/LightningTargetSystem.cs | 6 +++++
Resources/Prototypes/Entities/Mobs/base.yml | 3 +++
3 files changed, 31 insertions(+)
diff --git a/Content.Server/Lightning/Components/LightningTargetComponent.cs b/Content.Server/Lightning/Components/LightningTargetComponent.cs
index 6d806b3fe7e..12624b1aa62 100644
--- a/Content.Server/Lightning/Components/LightningTargetComponent.cs
+++ b/Content.Server/Lightning/Components/LightningTargetComponent.cs
@@ -69,4 +69,26 @@ public sealed partial class LightningTargetComponent : Component
///
[DataField]
public FixedPoint2 DamageFromLightning = 1;
+
+ // Triad: electrocution path. The Structural damage above no-ops on Biological damage containers,
+ // so mobs on the strike table took nothing. These make a strike electrocute the target instead;
+ // insulated gloves apply through the normal electrocution attempt.
+
+ ///
+ /// Triad: whether a lightning strike electrocutes this target (stun + shock damage).
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public bool ElectrocuteOnStrike;
+
+ ///
+ /// Triad: shock damage dealt by the electrocution.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int ElectrocutionShockDamage = 15;
+
+ ///
+ /// Triad: how long the electrocution lasts.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public TimeSpan ElectrocutionTime = TimeSpan.FromSeconds(5);
}
diff --git a/Content.Server/Lightning/LightningTargetSystem.cs b/Content.Server/Lightning/LightningTargetSystem.cs
index 4a0ee23c5b7..1c74afe8c35 100644
--- a/Content.Server/Lightning/LightningTargetSystem.cs
+++ b/Content.Server/Lightning/LightningTargetSystem.cs
@@ -1,3 +1,4 @@
+using Content.Server.Electrocution; // Triad
using Content.Server.Explosion.EntitySystems;
using Content.Server.Lightning;
using Content.Server.Lightning.Components;
@@ -12,6 +13,7 @@ namespace Content.Server.Tesla.EntitySystems;
public sealed class LightningTargetSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly ElectrocutionSystem _electrocution = default!; // Triad
[Dependency] private readonly ExplosionSystem _explosionSystem = default!;
[Dependency] private readonly TransformSystem _transform = default!;
@@ -24,6 +26,10 @@ public override void Initialize()
private void OnHitByLightning(Entity uid, ref HitByLightningEvent args)
{
+ // Triad: electrocution path for biological targets, which the Structural damage below no-ops on.
+ if (uid.Comp.ElectrocuteOnStrike)
+ _electrocution.TryDoElectrocution(uid, args.Source, uid.Comp.ElectrocutionShockDamage, uid.Comp.ElectrocutionTime, refresh: true);
+
DamageSpecifier damage = new();
damage.DamageDict.Add("Structural", uid.Comp.DamageFromLightning);
_damageable.TryChangeDamage(uid, damage, true);
diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml
index 69351eee1d4..5283f2e78e1 100644
--- a/Resources/Prototypes/Entities/Mobs/base.yml
+++ b/Resources/Prototypes/Entities/Mobs/base.yml
@@ -123,6 +123,9 @@
- type: LightningTarget
priority: 1 # Mono
lightningExplode: false
+ # Triad: bolts that overflow the coils and rods electrocute whoever they land on.
+ # Insulated gloves apply; lightningResistance stays 1 so the bolt can arc once more onward.
+ electrocuteOnStrike: true
# Used for mobs that can enter combat mode and can attack.
- type: entity
From 78229dc3a75985331c6086af139a7059443a6a0f Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 18:56:05 -0400
Subject: [PATCH 07/14] Retune tesla decay and mote threshold from Monte Carlo
simulation
Simulating the ball wander in a 3-wide cage showed the far side PA
lane misses about a third of waves, so effective Level-1 feed is
~7.3/s, not the ideal 10/s. Decay 10 starved the Level-1 ball dead;
7 idles it as designed. Mote threshold 120 -> 80 lands the target
ladder at the effective feed: ~6 motes at Level 2, ~22 at Level 3,
1.8 MW sustained harvest at a hacked Level-3 PA with a 12-coil ring.
---
.../Components/TeslaEnergyBallComponent.cs | 4 ++--
.../Structures/Power/Generation/Tesla/coil.yml | 6 +++---
.../Power/Generation/Tesla/energyball.yml | 17 +++++++++--------
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs b/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
index 1f65f8c5428..96e85b86179 100644
--- a/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
+++ b/Content.Server/Tesla/Components/TeslaEnergyBallComponent.cs
@@ -36,8 +36,8 @@ public sealed partial class TeslaEnergyBallComponent : Component
///
/// Triad: energy bled passively per second while the ball exists. 0 disables decay (upstream
- /// behavior, the default). The tesla prototype pins this to the Level-1 PA feed rate so Level 1
- /// is break-even: alive, no motes. See energyball.yml.
+ /// behavior, the default). The tesla prototype pins this to the effective Level-1 PA feed rate
+ /// so Level 1 idles the ball: alive, essentially no motes. See energyball.yml for the tuning.
///
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float PassiveEnergyDecay;
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index 609f0cc2395..755b3922cbb 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -75,9 +75,9 @@
hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
lightningResistance: 10
lightningExplode: false
- # Triad: durability for 9-hour rounds under the mote-heavy strike economy: ~4500 strikes to
- # destruction (~7h at a moderate PA level per coil). Stretch service intervals by welding
- # (Repairable) or spreading load across more coils.
+ # Triad: durability for 9-hour rounds under the mote-heavy strike economy: 4500 strikes to
+ # destruction. Simulated with a 12-coil ring: first coil death ~11h at PA Level 2, ~4h at a
+ # hacked Level 3. Stretch service intervals by welding (Repairable) or adding coils.
damageFromLightning: 0.05
- type: PowerNetworkBattery
maxSupply: 1000000
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
index 71b455cd85c..ae2d5c92460 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
@@ -73,15 +73,16 @@
consumeEntities: false
- type: TeslaEnergyBall
spawnProto: TeslaMiniEnergyBall
- # Triad: wild-tesla economy. Decay pinned to the Level-1 PA feed (3 emitters * 20 energy / 6s = 10/s)
- # so Level 1 is break-even (alive, no motes), Standby/Level 0 starves the ball, Level 2+ makes motes.
- # The deep despawn floor gives ~60s of grace under full starvation before collapse, since feed lands
- # in 6-second lumps and the stock -100 floor would kill it after barely two missed waves.
- passiveEnergyDecay: 10
+ # Triad: wild-tesla economy. Decay pinned to the EFFECTIVE Level-1 PA feed (~7.3/s from Monte
+ # Carlo, not the ideal 3 lanes * 20 / 6s = 10/s: the ball's wander in a 3-wide cage drops the far
+ # side lane about a third of the time). Level 1 idles the ball (alive, a stray mote every few
+ # minutes), Standby/Level 0 starves it, Level 2+ makes motes. The deep despawn floor gives ~85s
+ # of grace under full starvation, since feed lands in 6-second lumps.
+ passiveEnergyDecay: 7
energyToDespawn: -600
- # Mote count self-regulates: spawn rate = net feed / needEnergyToSpawn, motes live 120s, so
- # Level 3 (net +20/s) sustains 20*120/120 = 20 motes and Level 2 (net +5/s) sustains 5.
- needEnergyToSpawn: 120
+ # Mote count self-regulates: spawn rate = net feed / needEnergyToSpawn, motes live 120s.
+ # Simulated ladder at these numbers: Level 1 ~0.5 motes, Level 2 ~6, Level 3 ~22 sustained.
+ needEnergyToSpawn: 80
soundCollapse:
path: /Audio/Effects/tesla_collapse.ogg
params:
From 6179673dffae742c86f5ac7138fe06fd58b6ff70 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:00:36 -0400
Subject: [PATCH 08/14] Scale tesla strike energy to a ~7 MW Level-3 harvest
ceiling
Strike energy back to the upstream 2M but into a 12M bank, keeping
the 6-strike routing gradient. Catch dynamics depend only on the
strike-to-bank ratio, so saturation behavior and durability are
unchanged; output scales linearly. Simulated: ~2.6 MW at stock
Level 2, ~7.2 MW at a hacked Level 3 with a 12-coil ring.
---
.../Entities/Structures/Power/Generation/Tesla/coil.yml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index 755b3922cbb..2517c87b3cb 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -65,11 +65,13 @@
- type: Battery
# Triad: wild-tesla economy. A strike banks maxCharge/6, so the charge-headroom routing has a
# real gradient instead of one strike pegging the coil (upstream: 2M strike into a 1M bank).
- maxCharge: 3000000
+ # Sized from Monte Carlo for ~7 MW sustained at a hacked Level-3 PA with a 12-coil ring
+ # (~2.6 MW at stock Level 2).
+ maxCharge: 12000000
startingCharge: 0
- type: BatteryDischarger
- type: TeslaCoil
- chargeFromLightning: 500000 # Triad: was 2000000, see Battery note
+ chargeFromLightning: 2000000 # Triad: upstream value, but into a 12M bank instead of 1M — see Battery note
- type: LightningTarget
priority: 4
hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
From 5868488e389f4bca087838d815bc121ce0d006f1 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:05:27 -0400
Subject: [PATCH 09/14] Tesla coils become capacitors: one strike fills, tower
count is throughput
maxCharge drops to equal chargeFromLightning (2M) and supply throttles
to 300 kW, so a struck tower saturates, its strike bid floors, and the
routing round-robins bolts across the array while each bank trickles
out smoothly. Tower count becomes the harvest knob: simulated at a
hacked Level-3 PA, 12 towers ~3.5 MW, 24 ~6 MW, ~7 MW asymptote;
stock Level 2 with 12 towers ~2.5 MW. Bigger arrays also spread strike
damage: first coil death ~4.7h at 12 towers, ~11h at 32.
---
.../Power/Generation/Tesla/coil.yml | 20 +++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index 2517c87b3cb..0b37ec7de44 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -63,15 +63,16 @@
sprite: Structures/Power/Generation/Tesla/coil.rsi
state: coil
- type: Battery
- # Triad: wild-tesla economy. A strike banks maxCharge/6, so the charge-headroom routing has a
- # real gradient instead of one strike pegging the coil (upstream: 2M strike into a 1M bank).
- # Sized from Monte Carlo for ~7 MW sustained at a hacked Level-3 PA with a 12-coil ring
- # (~2.6 MW at stock Level 2).
- maxCharge: 12000000
+ # Triad: wild-tesla economy, capacitor model. One strike fills the bank; the full coil's strike
+ # bid floors (see TeslaCoilSystem) so the next bolt round-robins to a drained coil, and the bank
+ # trickles out through the throttled supply below. Tower count is therefore the throughput knob:
+ # Monte Carlo at a hacked Level-3 PA gives ~3.5 MW with 12 towers, ~6 MW with 24, ~7 MW asymptote
+ # (~2.5 MW at stock Level 2 with 12).
+ maxCharge: 2000000
startingCharge: 0
- type: BatteryDischarger
- type: TeslaCoil
- chargeFromLightning: 2000000 # Triad: upstream value, but into a 12M bank instead of 1M — see Battery note
+ chargeFromLightning: 2000000 # Triad: equals maxCharge on purpose — one strike saturates, see Battery note
- type: LightningTarget
priority: 4
hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
@@ -82,8 +83,11 @@
# hacked Level 3. Stretch service intervals by welding (Repairable) or adding coils.
damageFromLightning: 0.05
- type: PowerNetworkBattery
- maxSupply: 1000000
- supplyRampTolerance: 1000000
+ # Triad: throttled discharge is what makes tower count matter — each tower trickles its bank at
+ # 300 kW, so full harvest at a hacked Level-3 PA needs a ~24-tower array. The ~7s per-tower
+ # buffer also smooths the strike lumps into near-constant grid supply.
+ maxSupply: 300000
+ supplyRampTolerance: 300000
- type: Anchorable
- type: Rotatable
- type: Pullable
From 4db196a608bcde669e84c7cb353363c122f3c0bb Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:42:13 -0400
Subject: [PATCH 10/14] Tesla harvest peaks at 24 towers; ~2h service interval
at max output
Supply throttle 300 -> 500 kW moves the throughput knee to a 24-tower
array (simulated ~5.3 MW at 12 towers, ~7 MW peak at 24; more towers
add no output, only spread wear). Strike damage 0.05 -> 0.15 lands
the first tower death at ~2h on the max array, ~3.4h at stock
Level 2 with 12 towers. Welding rotation or extra towers stretch it.
---
.../Power/Generation/Tesla/coil.yml | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
index 0b37ec7de44..00b5128b9a7 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
@@ -66,8 +66,8 @@
# Triad: wild-tesla economy, capacitor model. One strike fills the bank; the full coil's strike
# bid floors (see TeslaCoilSystem) so the next bolt round-robins to a drained coil, and the bank
# trickles out through the throttled supply below. Tower count is therefore the throughput knob:
- # Monte Carlo at a hacked Level-3 PA gives ~3.5 MW with 12 towers, ~6 MW with 24, ~7 MW asymptote
- # (~2.5 MW at stock Level 2 with 12).
+ # Monte Carlo at a hacked Level-3 PA: ~5.3 MW with 12 towers, peaking at ~7 MW with 24; towers
+ # beyond 24 add no output, only spread wear (~2.6 MW at stock Level 2 with 12).
maxCharge: 2000000
startingCharge: 0
- type: BatteryDischarger
@@ -78,16 +78,16 @@
hitProbability: 0.5 # Triad: fallback only; with a working battery the coil bids by charge headroom (see TeslaCoilSystem)
lightningResistance: 10
lightningExplode: false
- # Triad: durability for 9-hour rounds under the mote-heavy strike economy: 4500 strikes to
- # destruction. Simulated with a 12-coil ring: first coil death ~11h at PA Level 2, ~4h at a
- # hacked Level 3. Stretch service intervals by welding (Repairable) or adding coils.
- damageFromLightning: 0.05
+ # Triad: 1500 strikes to destruction. Simulated: first tower death ~2h on a max-output 24-tower
+ # array at a hacked Level 3, ~3.4h at stock Level 2 with 12 towers. Weld (Repairable) on a
+ # service rotation, or add towers beyond 24 to spread wear.
+ damageFromLightning: 0.15
- type: PowerNetworkBattery
# Triad: throttled discharge is what makes tower count matter — each tower trickles its bank at
- # 300 kW, so full harvest at a hacked Level-3 PA needs a ~24-tower array. The ~7s per-tower
- # buffer also smooths the strike lumps into near-constant grid supply.
- maxSupply: 300000
- supplyRampTolerance: 300000
+ # 500 kW (4s recovery), sized so harvest at a hacked Level-3 PA peaks at a 24-tower array. The
+ # per-tower buffer also smooths the strike lumps into near-constant grid supply.
+ maxSupply: 500000
+ supplyRampTolerance: 500000
- type: Anchorable
- type: Rotatable
- type: Pullable
From c7c63480c5e4544e06434102d8c60856303a9e34 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:50:12 -0400
Subject: [PATCH 11/14] Tesla coil logistics: bulk crate of 12, buyable, Edison
starts with one
The Edison bulk crate holds a dozen flatpacks (was six) and gains a
cargo console listing, since Frontier abstracted the upstream
single-coil product and nothing sold coils at all. Edison map stock
trims to exactly one bulk crate: a 12-tower starter array out of the
box, with expansion bought through the console.
---
Resources/Maps/_NF/POI/edison.yml | 39 -------------------
.../PointsOfInterest/EdisonPort/entities.yml | 4 +-
.../_Triad/Catalog/Cargo/cargo_engines.yml | 12 ++++++
3 files changed, 14 insertions(+), 41 deletions(-)
create mode 100644 Resources/Prototypes/_Triad/Catalog/Cargo/cargo_engines.yml
diff --git a/Resources/Maps/_NF/POI/edison.yml b/Resources/Maps/_NF/POI/edison.yml
index 90e46479ba3..46f9eddf404 100644
--- a/Resources/Maps/_NF/POI/edison.yml
+++ b/Resources/Maps/_NF/POI/edison.yml
@@ -36438,23 +36438,6 @@ entities:
- type: Transform
pos: 33.5,-24.5
parent: 1
-- proto: CrateEngineeringTeslaCoil
- entities:
- - uid: 6050
- components:
- - type: Transform
- pos: 43.5,-23.5
- parent: 1
- - uid: 6051
- components:
- - type: Transform
- pos: 42.5,-23.5
- parent: 1
- - uid: 6052
- components:
- - type: Transform
- pos: 44.5,-23.5
- parent: 1
- proto: CrateEngineeringTeslaCoilBulk
entities:
- uid: 6053
@@ -80498,28 +80481,6 @@ entities:
- type: Transform
pos: 25.5,17.5
parent: 1
-- proto: TeslaCoilFlatpack
- entities:
- - uid: 12219
- components:
- - type: Transform
- pos: 46.438305,-23.349659
- parent: 1
- - uid: 12220
- components:
- - type: Transform
- pos: 46.713493,-23.386375
- parent: 1
- - uid: 12221
- components:
- - type: Transform
- pos: 46.493343,-23.569962
- parent: 1
- - uid: 12222
- components:
- - type: Transform
- pos: 46.823566,-23.569962
- parent: 1
- proto: TeslaGenerator
entities:
- uid: 12223
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/EdisonPort/entities.yml b/Resources/Prototypes/_NF/PointsOfInterest/EdisonPort/entities.yml
index fe68cd96662..b01db08b658 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/EdisonPort/entities.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/EdisonPort/entities.yml
@@ -196,12 +196,12 @@
id: CrateEngineeringTeslaCoilBulk
parent: CrateEngineeringSecure
name: bulk tesla coil crate
- description: A collection of six tesla coils. Attracts lightning and generates energy from it.
+ description: A dozen flatpacked tesla coils. Attract lightning and generate energy from it.
components:
- type: StorageFill
contents:
- id: TeslaCoilFlatpack
- amount: 6
+ amount: 12 # Triad: one crate = a starter array; two = the 24-tower max-output build
- type: entity
id: CrateEngineeringSingularityCollectorBulk
diff --git a/Resources/Prototypes/_Triad/Catalog/Cargo/cargo_engines.yml b/Resources/Prototypes/_Triad/Catalog/Cargo/cargo_engines.yml
new file mode 100644
index 00000000000..6d8b8e42fec
--- /dev/null
+++ b/Resources/Prototypes/_Triad/Catalog/Cargo/cargo_engines.yml
@@ -0,0 +1,12 @@
+# Triad: the upstream single-coil product (EngineTeslaCoil) is abstract via Frontier, so this is
+# the only console path to tesla coils. One bulk crate is a 12-tower starter array; two build the
+# 24-tower max-output ring.
+- type: cargoProduct
+ id: EngineTeslaCoilBulk
+ icon:
+ sprite: Structures/Power/Generation/Tesla/coil.rsi
+ state: coil
+ product: CrateEngineeringTeslaCoilBulk
+ cost: 10000
+ category: cargoproduct-category-name-engineering
+ group: market
From c007c72376a7a566459b5192ecc1787757b7278e Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:50:12 -0400
Subject: [PATCH 12/14] Update tesla guidebook for the wild economy
Documents feeding and starvation (including starving out a tesloose),
mote generation scaling with accelerator power, capacitor coils with
the arcing charge indicator, potential-difference strike preference,
wear and welding, and real crew electrocution. Deliberately does not
mention the accelerator limiter.
---
.../Guidebook/Engineering/TeslaEngine.xml | 46 ++++++++++++-------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
index 168f6253a8a..9a023064f7a 100644
--- a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
+++ b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
@@ -1,4 +1,4 @@
-
+
# Tesla Engine
The Tesla Engine is a powerful generator that uses a contained ball of lightning to produce energy for the station.
@@ -10,11 +10,23 @@
It generates power by harnessing the lightning strikes produced by the lightning ball using Tesla Coils.
+ ## Feeding the Ball
+ The lightning ball constantly bleeds energy into space. It must be continuously fed by a running Particle Accelerator, or it will starve, shrink, and collapse within a couple of minutes.
+
+ How hard you feed it matters:
+ - At low accelerator power the ball merely survives, producing only its own occasional strikes.
+ - Fed harder, the ball builds surplus energy and sheds it as miniature ball lightning, which orbit the containment field and fire strikes of their own.
+ - The more miniature balls in orbit, the more lightning, and the more power your coils can harvest. A well-fed tesla is dramatically more generous, and dramatically more dangerous.
+
+
+
+
+
## Containment Field
The Tesla Engine requires a containment field to prevent the lightning ball from escaping and destroying the station.
It is suggested to use the minimum size containment field for the lightning ball.
- Larger containment fields allow the lightning ball to reach closer to sensitive equipment and potentially strike it, ignoring placed grounding rods and tesla coils.
+ A tight cage keeps the ball centered in the accelerator's particle stream, and keeps it away from sensitive equipment beyond the field.
@@ -33,18 +45,16 @@
## Lightning Strikes
- When the Tesla Engine is active, the lightning ball will periodically strike objects surrounding it.
-
- The Tesla prefers to strike some objects more than others, such as Tesla Coils and Grounding Rods.
+ When the Tesla Engine is active, the lightning ball and its miniature balls will periodically strike objects surrounding them.
- If the tesla can't find any Tesla Coils or Grounding Rods to strike first, it will strike almost any station object capable of being powered, such as Substations, APCs, and general machinery.
+ Lightning seeks the largest difference in electrical potential. An empty Tesla Coil is the most attractive target on the station; a fully charged one is nearly ignored. Grounding Rods are always willing targets and sit just below coils in preference.
- Certain objects aren't struck by the tesla, such as batteries, lights, PDAs, and other handheld items.
+ If the tesla can't find any Tesla Coils or Grounding Rods to strike, it will strike almost any station object capable of being powered, such as Substations, APCs, and general machinery.
- It will also strike mobs and crew members, shocking them. Make sure to wear insulated gloves before approaching it.
+ It will also strike mobs and crew members, electrocuting them. Make sure to wear insulated gloves before approaching it, and keep spectators away from a heavily fed engine.
## Tesla Coils
- Lightning strikes can be harnessed using Tesla Coils, which convert the lightning strikes into power for the station.
+ Lightning strikes are harnessed using Tesla Coils, which store each strike and feed it to the grid.
@@ -52,13 +62,13 @@
- Tesla Coils should be placed around the lightning ball to capture the energy from lightning strikes, as well as to prevent the lightning from striking sensitive equipment further away.
+ A single strike fully charges a coil's internal bank. While it holds charge the coil arcs visibly and discharges into the grid at a steady rate; lightning avoids it in favor of empty coils, so strikes naturally spread themselves across the array.
- Tesla Coils take damage every time they are struck by lightning, and will eventually break if not repaired.
- Be sure to monitor the condition of the Tesla Coils and repair them as needed.
+ Ring the containment field with coils. Output grows with every coil you add until each bolt reliably finds an empty coil waiting; beyond that point, additional coils add no output but spread the wear.
- When lightning strikes Tesla Coils, they fill an internal battery, which is rapidly discharged to the grid.
- It will discharge this power even if there is no consumer to take it, so it's a good idea to have an SMES nearby to store the power and discharge it smoothly.
+ Coils take damage every time they are struck, and a hard-driven array needs regular attention. Watch for cracks and repair coils with a welder before they fail, or stock spares.
+
+ A coil arcing is normal, it is simply holding charge. If the entire array arcs continuously, your grid isn't drawing enough power: add SMES capacity to soak up the surplus, or the engine will waste its strikes.
## Grounding Rods
Grounding Rods help protect sensitive equipment from being struck and prevent a loosed tesla (tesloose).
@@ -76,7 +86,7 @@
Grounding rods do not take damage from lightning strikes.
- This makes them beneficial for forming a saftey net of grounding rods to rely on in case the tesla coils are damaged or destroyed.
+ This makes them beneficial for forming a safety net of grounding rods to rely on in case the tesla coils are damaged or destroyed.
Engineers should use grounding rods to protect sensitive equipment from lightning strikes, such as the Emitters powering the containment field generators.
@@ -84,7 +94,7 @@
If the lightning ball escapes the containment field, it is referred to as a loosed tesla, or tesloose.
An escaped tesla will randomly walk around the station, attracted to objects that can be powered, such as APCs, Substations, and machinery.
- It will also gladly strike crew members and mobs, shocking them.
+ It will also gladly strike crew members and mobs, electrocuting them.
Wearing insulated gloves will protect you from being shocked by the tesla, but it won't prevent the tesla from striking you.
@@ -92,7 +102,9 @@
- The tesla can be destroyed by firing antiparticles at it using a Portable Particle Decelerator, however, the Tesla is much more powerful than the Singularity, and it will take a lot of antiparticles to destroy it.
+ Remember that the ball starves without its accelerator. Shut the Particle Accelerator down and a loose ball will collapse on its own within a couple of minutes, provided it doesn't find enough to eat along the way. Evacuate its path, cut the feed, and wait it out.
+
+ The tesla can also be destroyed by firing antiparticles at it using a Portable Particle Decelerator, however, the Tesla is much more powerful than the Singularity, and it will take a lot of antiparticles to destroy it.
A group of people using decelerators is recommended to destroy a tesloose.
Portable Particle Decelerators can be either researched and made by the Research Department, or they can be bought from Cargo.
From 5e86b3cb9a81d3bcd6609c16d7903f2c9098b11e Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:57:39 -0400
Subject: [PATCH 13/14] Guidebook: a tesloose is already starving
Containment failure means the ball has left the particle stream, so
it is cut off from feed the moment it escapes. Drop the shut-down-the-
PA advice and document the real behavior: it collapses on its own
within a few minutes, and decelerators just speed that up.
---
Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
index 9a023064f7a..70b30f470ba 100644
--- a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
+++ b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
@@ -102,9 +102,9 @@
- Remember that the ball starves without its accelerator. Shut the Particle Accelerator down and a loose ball will collapse on its own within a couple of minutes, provided it doesn't find enough to eat along the way. Evacuate its path, cut the feed, and wait it out.
+ Remember that the ball starves without its accelerator. An escaped ball has left the particle stream behind, so it is already dying: expect it to collapse on its own within a few minutes. Evacuate its path and let it burn itself out.
- The tesla can also be destroyed by firing antiparticles at it using a Portable Particle Decelerator, however, the Tesla is much more powerful than the Singularity, and it will take a lot of antiparticles to destroy it.
+ To end it faster, fire antiparticles at it using a Portable Particle Decelerator, however, the Tesla is much more powerful than the Singularity, and it will take a lot of antiparticles to destroy it.
A group of people using decelerators is recommended to destroy a tesloose.
Portable Particle Decelerators can be either researched and made by the Research Department, or they can be bought from Cargo.
From 18a5cb996def1f6abefff428b5837a1ca777b2f0 Mon Sep 17 00:00:00 2001
From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com>
Date: Tue, 28 Jul 2026 19:58:21 -0400
Subject: [PATCH 14/14] Guidebook: drop particle decelerator advice
Decelerators are unobtainable on this fork: Frontier abstracted the
cargo product and commented the gun out of research and the lathe
pack. Waiting out the starving ball is the actual tesloose response.
---
.../ServerInfo/Guidebook/Engineering/TeslaEngine.xml | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
index 70b30f470ba..5ca71f3b99e 100644
--- a/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
+++ b/Resources/ServerInfo/Guidebook/Engineering/TeslaEngine.xml
@@ -102,16 +102,6 @@
- Remember that the ball starves without its accelerator. An escaped ball has left the particle stream behind, so it is already dying: expect it to collapse on its own within a few minutes. Evacuate its path and let it burn itself out.
-
- To end it faster, fire antiparticles at it using a Portable Particle Decelerator, however, the Tesla is much more powerful than the Singularity, and it will take a lot of antiparticles to destroy it.
- A group of people using decelerators is recommended to destroy a tesloose.
-
- Portable Particle Decelerators can be either researched and made by the Research Department, or they can be bought from Cargo.
-
-
-
-
-
+ Remember that the ball starves without its accelerator. An escaped ball has left the particle stream behind, so it is already dying: expect it to collapse on its own within a few minutes. Evacuate its path, keep your distance, and let it burn itself out.