A component is a device that goes on a ship: a reactor, a shield generator, a
weapon, a sensor array, a life support unit. Components are where a ship's behavior
actually comes from — the hull is mostly geometry.
A complete example
<component id="Deflector Shields" name="Deflector Shields" type="Shield" function="Consume"
hardpoints="4" integrity="100" tolerance="0.9" auto-enable="true" weight="100">
<energy min="0" max="2000" idle="100" optimal="1000" level="0" charge="5" bleed="10" consumebylevel="true" />
<frequency min="1" max="999" value="500" />
<properties>
<property id="Format">4</property>
<property id="Rate">5</property>
<property id="RechargeDelay">4</property>
<property id="RechargeDelayCollapsed">10</property>
</properties>
<traits>
<trait id="Concussive">0.75</trait>
<trait id="Electrical">1.25</trait>
</traits>
<widgets>
<widget role="Tactical" source="shield" group="Defensive" />
<widget role="Engineer" source="shield-frequency" group="Defensive" />
</widgets>
<sounds startup="" activated="ShieldsUp" deactivated="ShieldsDown" />
</component>
Each component is its own file, saved as
Components/<Type>_<id>.xml in its module.
Type and function
Type is what kind of device it is, and the game reasons about types
directly — alert conditions restrict types, not individual components. The list
includes Power, Shield, Weapon, WeaponSystem, Sensor, Sight, Propulsion, Maneuver,
VectoredThrusters, Ftl, Jump, Cloak, Inhibit, Tracker, Battery, Conduit, Armor, Compute,
Environment, Locomotion, Rotation, Rotor, Wing, Group, Generic and Special.
The type also decides where a component can go: it installs only on a hard point of
the same type, or on one whose type is Any. The value is case‑sensitive,
and a misspelled type spoils the rest of the record, so copy it exactly. The editor's
Type list does not offer Sight, Rotor or Wing; those are written in the XML, and the
editor keeps them when it saves.
Alert conditions match a component by its tags, which always include its type in
lower case. A component can carry extra <tags> to fall under a
restriction its type would not.
Function is how it relates to energy: Generate,
Store, Consume or Transfer. A reactor is a source
because it is type Power and function Generate; its output is its optimal level
times its yield, scaled by its charge and its integrity. A Battery stores surplus
whatever its function says, and every other type draws power.
Energy is the balance knob
The energy block is where a component's whole feel is decided:
- idle — draw when doing nothing. It defaults to the charge rate.
- optimal — the design point. What "100%" means to
Engineer.
- max — the ceiling, deliberately above optimal. The gap between
them is how much overcharge headroom the device has, and it is a design decision, not
a rounding artifact. The example allows 200%.
- charge and bleed — how fast it fills and how
fast it leaks.
- level — the level it starts at.
- min — despite sitting here, the minimum integrity the device needs
to run. Below it, the component will not start and shuts down if running.
- yield — an optional multiplier on what the device delivers
(default 1); activate is an optional one‑off cost to switch it on.
min, max, optimal, level,
charge and bleed are all required. Leave one out and the
component loads without anything after its energy block.
Properties
Properties are the type‑specific numbers. A shield's Format is how
many segments it has (4 for fore/starboard/aft/port, 2 for fore and aft, 1 for a single
bubble). Rate is how fast a segment recharges while the shield is up, and
IdleRate how fast while it is online but lowered.
RechargeDelay and RechargeDelayCollapsed are the pause, in
seconds after a hit, before a segment starts recovering, and the deliberately much longer
pause after one has collapsed to zero. That pair is the reason Tactical cares about
balancing shields before a facing fails rather than after.
Both delays default to 0, meaning no pause, and a hit that empties a segment uses
only RechargeDelayCollapsed. Set both. The editor's shield panel has rows
for Format, Rate and IdleRate only; add the two delays as custom properties.
Other types read their own keys. A few worth knowing:
- Locomotion —
ThrottleAdjustment scales one
chassis's forward top speed (default 1) without touching its reverse.
- Ftl —
Spool-Time is the countdown in seconds before
the jump (default 3; 0 jumps at once), and Spool-Sound the
sound bank entry played while it spools.
- Wing — a fixed‑wing drive: engine thrust, lift from the wing, a
stick‑flown attitude. Its keys cover the airframe (
WingLoading,
EnginePower, the three torques), the wing (MaxLiftCoefficient,
MaxAttackAngle), the controls, boost, and an Ai… family for
how an NPC flies it. There is no landing gear; gravity comes from the map.
- VectoredThrusters —
BoosterEffect,
BoosterSite, BoosterSound and ChuteSound dress
the boost and the chute, and the Ai… keys tune how an NPC drives it.
The editor has typed panels for the common keys of several types. Anything not on a
panel goes in as a custom property with the same id.
Traits
Traits are multipliers against damage kinds — the shield above is meant to resist
concussive damage and be vulnerable to electrical. They load with the component, but the
game does not currently apply them: a component's traits change no damage today. The
resistances that do work belong to the hull. A vessel class's hull-type
names an entry in the module's World/hull-types.xml, and that entry's
<resistance name="Concussive" resistance="0.75" /> rows scale the
damage the hull takes.
Components bring their own console panels
This is the part worth understanding properly, because it is the main extension
point in the whole client.
A component's <widgets> block declares which role's console gets
which panel, and in which group on that console:
<widget role="Tactical" source="shield" group="Defensive" />
<widget role="Engineer" source="shield-frequency" group="Defensive" />
When a vessel has this component installed, the Tactical console grows a shield
panel and the Engineer console grows a shield frequency panel. Nobody edits a console
page to make that happen; the console has a container for each role and group, and it
mounts whatever the installed components declare.
The component editor has no panel for this block, so write it in the file. The
editor keeps it when it saves.
So the honest way to add a new capability to Horizons is: write a widget,
write a component that declares it, install the component on a hull. The console
follows.
Other fields
- hardpoints — the component's size. It fits a hard point whose
size is at least this; a component always occupies one hard point.
- integrity and tolerance — integrity is how much
damage it can take. Tolerance, from 0 to 1, is how well it stands being run above 100%:
the higher it is, the less overcharging wears it down.
- auto-enable — whether it switches itself on when it comes online.
The alert condition is not checked at that moment; it applies at the next change of
condition or when someone switches the device on by hand.
- invincible — set it to
true and the component takes
no damage. XML only.
- frequency — for shields and weapons. The
value is
re‑rolled between min and max when the component is installed,
and weapon fire takes its frequency from the ship's WeaponSystem component. See
Tactical.
- upgrades —
<upgrades slots="N" />, the number of
component parts it can be fitted with. See below.
- sounds — ambient, startup, activation, use, deactivation, shutdown
and destruction, drawn from a sound bank. Ambient plays only on player
vessels.
- economy —
<economy base-value="…" />, the base
value trade starts from.
Sounds are worth filling in. A shield that says ShieldsUp when it comes
online is most of what makes the moment land for the crew.
Component parts
A component part is an upgrade that fills one of a component's upgrade slots. Parts
are their own records, edited from the module's Commodities › Component
Parts section, and saved together in World/component-parts.xml:
<component-part id="Tuned Emitter" faction="" manufacturer="" visible="true" tags="">
<description /><icon /><image /><pedia />
<buffs>
<buff target="Component" affects="Level" units="Percentage" value="0.05" />
</buffs>
</component-part>
A buff's affects names what it improves. On a component that can be
Charge, Level (the optimal level), IdleLevel, Yield, Tolerance or the heat values, plus
Damage and Range on a weapon; a buff aimed at Ordnance can raise Range.
Percentage is a fraction of the base value (0.05 is +5%), and several parts
add up rather than compound. Points adds the value as it stands. The editor
only offers the combinations the game reads.
During play, the Game Master fits a part from the Object panel by clicking an
upgrade slot on a hard point. Only the first six slots can be filled that way.