Skip to content

ships.Class.ShipLoadout

github-actions[bot] edited this page Aug 26, 2026 · 74 revisions

@elite-dangerous-almanac/core / ships / ShipLoadout

Class: ShipLoadout

Defined in: src/ships/ship-loadout.ts:539

A fitted ship — read a SLEF export, or assemble a hull from scratch.

Member index

Properties against methods

A property is a fact this build already carries; a method does something. Every getter above is an identity, an aggregate figure, or what a capture stated — it computes nothing, takes no options, and never throws. Everything that does work is a call: reading the catalogues, enumerating mounts, editing the fit, exporting it, and every figure on BuildMetrics.

The rule makes the split predictable, not harmless. Two of those calls take no argument and read like facts — validation(), which revalidates the whole fit, and fittedModules(), which allocates and deeply freezes a fresh snapshot on every call — so they are methods by the rule above even though a reader may reach for them as properties. A forgotten () still hands you the function rather than the value, and in plain JavaScript nothing complains: build.fittedModules is a function reference, build.fittedModules() is the list. TypeScript catches it; a .js consumer will not.

Example

Read a build a player already flies, and ask it what an outfitting screen shows. Every figure below is one build's — a Krait Phantom explorer. Figures the capture already stated — unladenMass here — are trusted verbatim while the fit they describe survives import; the rest are computed from the fit.

import { BuildMetrics } from '@elite-dangerous-almanac/core/ships/build-metrics';
import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';
import type { LoadoutEvent } from '@elite-dangerous-almanac/core/ships/slef';

// A `Loadout` line lifted from a player journal, parsed.
declare const event: LoadoutEvent;

const build = ShipLoadout.fromLoadout(event);

build.shipSymbol; // -> 'krait_light'
build.shipName; // -> 'Jenny Longuet'
build.unladenMass; // -> 388.830017   (tonnes)

const metrics = BuildMetrics.of(build);
metrics.maxJumpRange(); // -> 60.5478   (ly, best single jump)
metrics.powerBudget().withinBudget; // -> true
metrics.shieldMetrics()?.strength; // -> 743.12  (MJ)
metrics.armourMetrics().hitPoints; // -> 307.8

Accessors

cargoCapacity

Get Signature

get cargoCapacity(): number

Defined in: src/ships/ship-loadout.ts:848

Cargo capacity, in tonnes — a capture's CargoCapacity on the same terms as unladenMass, otherwise the sum of the fitted racks.

Returns

number


fuelCapacity

Get Signature

get fuelCapacity(): FuelCapacity

Defined in: src/ships/ship-loadout.ts:832

Fuel-tank capacities, in tonnes — a capture's FuelCapacity on the same terms as unladenMass, otherwise the fitted tanks plus the hull's own reserve.

Returns

FuelCapacity


hullValue

Get Signature

get hullValue(): number | null

Defined in: src/ships/ship-loadout.ts:870

Hull cost in credits represented by the build, or null if unknown.

Remarks

This is the live figure, kept coherent with edits: an import's own HullValue until something invalidates it. For the capture's figure as captured — which no edit changes — read sourcePurchase.

Returns

number | null


importOutcomes

Get Signature

get importOutcomes(): readonly LoadoutImportOutcome[]

Defined in: src/ships/ship-loadout.ts:946

Changes made while importing this build, in source order, followed by the fixed mounts stocked from the hull defaults because the source named none, in the defaults' own order.

Remarks

Each entry names the exact slot, and the source identity where the source gave one. emptied means an unknown module was removed from a removable mount; defaulted names the stock article fitted to armour, a core internal or the cargo hatch, with a null sourceSymbol when the source named nothing there at all.

Returns

readonly LoadoutImportOutcome[]

A deeply frozen list. It is empty for builds created with ShipLoadout.empty or ShipLoadout.default, and for imports that needed no normalization.


modulesValue

Get Signature

get modulesValue(): number | null

Defined in: src/ships/ship-loadout.ts:881

Fitted-modules cost in credits represented by the build, or null if unknown — including after an edit or import normalization discarded an import's figure, since no catalogue records what a replaced module was bought for. Unlike mass and capacity it is not recomputed from what remains; sourcePurchase keeps the captured figure and BuildMetrics.buildCost prices the current fit.

Returns

number | null


rebuy

Get Signature

get rebuy(): number | null

Defined in: src/ships/ship-loadout.ts:891

Insurance rebuy cost in credits represented by the build, or null if unknown. Discarded by an edit or by import normalization for the same reason as modulesValue, and likewise kept by sourcePurchase; BuildMetrics.buildCost rebuys the current fit at catalogue prices instead.

Returns

number | null


shipIdent

Get Signature

get shipIdent(): string | null

Defined in: src/ships/ship-loadout.ts:803

The player-given ID plate, or null if the build has none.

Returns

string | null


shipName

Get Signature

get shipName(): string | null

Defined in: src/ships/ship-loadout.ts:798

The player-given ship name, or null if the build has none.

Returns

string | null


shipSymbol

Get Signature

get shipSymbol(): string

Defined in: src/ships/ship-loadout.ts:793

The hull's internal id, e.g. "explorer_nx".

Returns

string


sourcePurchase

Get Signature

get sourcePurchase(): SourcePurchaseRecord | null

Defined in: src/ships/ship-loadout.ts:928

What the capture this build came from said was paid for it — a read-only SourcePurchaseRecord, or null for a build assembled here or imported from a capture that quoted no credits at all.

Remarks

The record is provenance about the source, so it is fixed at import and survives every edit: fit, remove or engineer whatever you like and it still reports the figures the capture carried, for the modules the capture carried them for. That is what hullValue, modulesValue and rebuy cannot do — they describe the build in hand, so an edit that invalidates one drops it.

A captured price belongs to one commander's purchase history, discounts included; the library's own figures are catalogue retail. Export quotes retail unless asked otherwise — see LoadoutExportOptions.credits.

Example
import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';
import { getSourceModuleValue } from '@elite-dangerous-almanac/core/ships/source-purchase';

declare const slefJson: string;

const build = ShipLoadout.fromSlef(slefJson);
const paid = build.sourcePurchase!;
paid.hullValue; // -> 189326510, as captured
getSourceModuleValue(paid, 'powerplant')?.value; // -> what that plant cost its owner

build.removeModule('Slot05_Size4');
build.modulesValue;                 // -> null   unavailable after the edit
paid.modulesValue;                  // -> 192625195, the captured figure
Returns

SourcePurchaseRecord | null


unladenMass

Get Signature

get unladenMass(): number

Defined in: src/ships/ship-loadout.ts:816

Hull + modules mass with an empty tank and no cargo, in tonnes.

Remarks

A capture's own UnladenMass stands while the fit it described survives import (see fromLoadout); otherwise this is the hull's hullMass plus every fitted module's post-engineering mass, and importOutcomes is the only report that the figure is the normalized fit's rather than the capture's.

Returns

number

Methods

applyBlueprint()

applyBlueprint(slotKey, blueprintSymbol, options): this

Defined in: src/ships/ship-loadout.ts:1580

Engineer the module in a slot — apply a blueprint (with a grade and quality) and an optional experimental effect, computing the resulting stat modifiers.

The modifiers are stored on the fitted module with journal-equivalent labels and Frontier's float32 arithmetic, so the build's own calculations pick them up. The block keeps the BlueprintName you passed. Weapon recipe internals such as BurstInterval are exposed as the derived RateOfFire and DamagePerSecond labels a journal writes, and module-specific aliases use the journal spelling too (MaximumRange, Range); recipe-only values a journal serializes no label for stay available through FittedModule.effectiveStats, which is what keeps burst and reload-cycle calculations faithful.

Which recipe an id names can depend on the module. The game writes Sensor_LongRange for both a sensor suite's modification and a utility scanner's, and the two roll different stats in opposite directions, so the id is resolved against the module's own menu before anything is computed. Reading a stored block back means resolving it the same way: resolveBlueprintForModule in ships/blueprint-journal is that lookup.

Parameters

slotKey

string

The slot whose module to engineer, matched case-insensitively (journal spelling).

blueprintSymbol

string

The blueprint recipe's Frontier symbol, e.g. "FSD_LongRange".

options

ApplyBlueprintOptions

ApplyBlueprintOptions: grade (1–5), optional quality (0–1, default 1), and optional experimental effect symbol. A nullish experimental means no effect, the same as leaving it out. Each is read once, before anything is checked, so an accessor cannot answer the check and the use differently.

Returns

this

this, for chaining.

Throws

If the slot is empty, or the blueprint/grade/experimental is unknown, or quality is outside [0, 1].

Throws

If slotKey or blueprintSymbol is not a string, options is not an object, or options.experimentalEffectSymbol carries a value that is not a string — a nullish one is no effect, not a wrong type. Also if the fitted module has no stats to engineer, is final and accepts no further engineering, is not offered the blueprint by its own menu, is not offered the experimental effect by it, or the id names a fixed event-reward identity rather than a craftable recipe — use setPreEngineeredVariant for those. Finally, if the catalogue does not carry every base stat the recipe modifies: incomplete engineering is rejected rather than stored as a partial journal modifier block.

Example

import { BuildMetrics } from '@elite-dangerous-almanac/core/ships/build-metrics';
import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
import { CORE_MODULES } from '@elite-dangerous-almanac/core/ships/modules-core';
import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

const fsd = getModuleBySymbol('Int_Hyperdrive_Size6_Class5', CORE_MODULES)!;

build.setModule('FrameShiftDrive', fsd)
     .applyBlueprint('FrameShiftDrive', 'FSD_LongRange', {
         grade: 5,
         experimentalEffectSymbol: 'special_fsd_heavy',
     });
BuildMetrics.of(build).maxJumpRange(); // uses the engineered optimal mass

availableBlueprints()

availableBlueprints(slotKey): readonly AvailableBlueprint[]

Defined in: src/ships/ship-loadout.ts:1154

Return the computable blueprint candidates for a fitted module symbol.

Parameters

slotKey

string

Slot key, matched case-insensitively.

Returns

readonly AvailableBlueprint[]

Frozen blueprint descriptors: the ordinary engineering menu first, then bespoke Mercenary upgrade recipes. An 'ordinary' candidate is available to the stock module; a 'mercenary' candidate is purchase-specific. Applying that bespoke blueprint identifies the matching Mercenary article even though its bare module symbol does not. Returns an empty array when the slot is empty, unresolved or final, or the module symbol has neither route.

Throws

If slotKey is not a string.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.availableBlueprints('FrameShiftDrive').map(({ blueprintSymbol }) => blueprintSymbol);

availableExperimentalEffects()

availableExperimentalEffects(slotKey): readonly string[]

Defined in: src/ships/ship-loadout.ts:1178

Return the computable experimental effects offered to a fitted module.

Parameters

slotKey

string

Slot key, matched case-insensitively.

Returns

readonly string[]

Frozen Frontier effect ids in engineering-menu order, or an empty array when the slot is empty, unresolved, final, or has no experimental menu.

Throws

If slotKey is not a string.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.availableExperimentalEffects('FrameShiftDrive');
// -> ['special_fsd_heavy', ...]

clearEngineering()

clearEngineering(slotKey): this

Defined in: src/ships/ship-loadout.ts:2251

Strip engineering from a slot's module, restoring its base stats.

Parameters

slotKey

string

The slot to de-engineer, matched case-insensitively (journal spelling).

Returns

this

this, for chaining. A no-op if the slot is empty or unmodified.

Throws

If slotKey is not a string, or the fitted article is final pre-engineered and its baked engineering cannot be removed.

Remarks

Clearing a Mercenary article removes its purchase-exclusive blueprint identity. Its FittedModule.preEngineeredVariant then reads null.


completeEngineeringGrade()

completeEngineeringGrade(slotKey): EngineeringNormalizationResult

Defined in: src/ships/ship-loadout.ts:1983

Recompute the fitted module's current engineering identity at quality 1.

Imported modifier values remain authoritative until this method is called. An ordinary or Mercenary recipe is rerolled through the package calculator; a fixed reward rebuilds its hand-authored modifiers and optional effect without losing its purchase identity. A refusal never changes the loadout.

A block that names a blueprint and grade but states no Modifiers at all is rolled here too, even at quality 1 — SLEF permits that identity-only shape and Inara writes it, so a capture of a completed roll would otherwise stay stock. A stated modifier array, empty or partial, is left alone at quality 1.

Parameters

slotKey

string

The engineered slot, matched case-insensitively.

Returns

EngineeringNormalizationResult

A frozen result identifying a normalized, unchanged or unsupported state.

Throws

If slotKey is not a string.

Example

import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

const partial = ShipLoadout.default('SideWinder').applyBlueprint(
    'FrameShiftDrive',
    'FSD_LongRange',
    { grade: 5, quality: 0.42 },
);
const imported = ShipLoadout.fromLoadout(partial.toLoadoutEvent());
imported.completeEngineeringGrade('FrameShiftDrive').kind; // -> 'normalized'
imported.fittedModuleAt('FrameShiftDrive')?.engineering?.Quality; // -> 1

fittedModuleAt()

fittedModuleAt(slotKey): FittedModule | null

Defined in: src/ships/ship-loadout.ts:1088

A deeply frozen, point-in-time view of the module in a slot.

Parameters

slotKey

string

Slot key, matched case-insensitively.

Returns

FittedModule | null

A detached, frozen view, or null when the slot is empty or unknown.

Throws

If slotKey is not a string.


fittedModules()

fittedModules(): readonly FittedModule[]

Defined in: src/ships/ship-loadout.ts:1124

Every fitted module as a deeply frozen point-in-time view.

Returns

readonly FittedModule[]

Detached module snapshots in the order the build carries them. The array and every nested record are frozen; query again after an edit for current state.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.fittedModules().map((module) => `${module.slot}: ${module.symbol}`);

modulesForSlot()

modulesForSlot(slotKey): OutfittingModule[]

Defined in: src/ships/ship-loadout.ts:1208

The modules that fit a given slot — its size, kind and any restriction all satisfied, with candidates that would worsen a one-per-ship or module-count limit omitted.

Parameters

slotKey

string

The slot key to fit, matched case-insensitively (journal spelling).

Returns

OutfittingModule[]

The fitting modules, in complete-catalogue order.

Remarks

This is the outfitting offer, so the fifteen grantOnly articles are never in it: each is a second identity for a module the game already sells — Int_Engine_Size2_Class1_free is the 2E Thrusters — and listing both puts the same article on the screen twice, once with no price. A build that already carries one keeps it; only the choices are filtered.

Throws

If the hull has no slot with that key.

Throws

If slotKey is not a string.

Example

import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

ShipLoadout.empty('Anaconda').modulesForSlot('FrameShiftDrive');

removeModule()

removeModule(slotKey): this

Defined in: src/ships/ship-loadout.ts:1476

Empty a slot.

Parameters

slotKey

string

The slot key to clear, matched case-insensitively (journal spelling).

Returns

this

this, for chaining. Clearing an already-empty removable slot is a no-op.

Throws

If slotKey is not a string.

Throws

If the slot is the built-in cargo hatch; is a required core or armour mount; or removing the module would worsen a per-ship module-count excess. Required mounts may be replaced with setModule but cannot be emptied.


repairFixedMount()

repairFixedMount(slotKey): FixedMountRepairResult

Defined in: src/ships/ship-loadout.ts:1253

Refit a fixed mount from this hull's stock loadout.

Parameters

slotKey

string

Fixed slot key, matched case-insensitively.

Returns

FixedMountRepairResult

A frozen FixedMountRepairResult. Refusals leave the build unchanged.

Remarks

This is the repair path for the mounts setModule does not expose as ordinary edits — in practice the built-in cargo hatch. The stock article keeps the mount's On, Priority and Health and none of the replaced module's engineering or captured value, as import normalization does. Every entry point already fills these mounts, so a build this package produced answers unchanged.

Throws

If slotKey is not a string.

Throws

If a known hull has no slot with that key.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const imported: ShipLoadout;
imported.repairFixedMount('CargoHatch').status; // -> 'unchanged'

setExperimentalEffect()

setExperimentalEffect(slotKey, experimental): ExperimentalEffectMutationResult

Defined in: src/ships/ship-loadout.ts:1776

Add, replace or remove only the fitted module's experimental effect.

Ordinary and Mercenary engineering is recomputed at its current blueprint, grade and quality. A fixed reward instead retains its hand-authored modifiers and purchase identity while the requested effect is composed with them. Refused edits leave the build unchanged and return stable structured data.

Parameters

slotKey

string

The engineered slot, matched case-insensitively.

experimental

string | null

Experimental-effect symbol, or null to remove the effect.

Returns

ExperimentalEffectMutationResult

A frozen result identifying an update, no-op or lossless refusal.

Throws

If slotKey or a non-null experimental is not a string.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.setExperimentalEffect('FrameShiftDrive', 'special_fsd_heavy');
build.setExperimentalEffect('FrameShiftDrive', null);

setModule()

setModule(slotKey, module): this

Defined in: src/ships/ship-loadout.ts:1357

Fit a module into a slot, replacing whatever is there.

Parameters

slotKey

string

The slot key to fit into, matched case-insensitively (journal spelling). An occupied slot keeps the key the build already spells it with, so fitting into an import never renames one of its mounts.

module

OutfittingModule

The module to fit (resolve it from a catalogue first, e.g. with getModuleBySymbol). The complete record is snapshotted, so a result from getPreEngineeredStats or a record you adjusted yourself keeps its stats — but it must name an article the built-in catalogue carries, and it may not drop that article's mass, cargoCapacity or fuelCapacity, which every build sums, nor state one as anything but a finite number.

Returns

this

this, for chaining.

Remarks

This is an incremental editor: every call must avoid worsening the current build's module-count excess, so fit an allowance-increasing module before the weapons it permits. Use ShipLoadout.fromLoadout to consume a complete snapshot instead, where order does not matter.

Fitting is a fresh mount: the slot's On, Priority and Health are reset. Set them again if your screen keeps a priority group across a swap.

Throws

If the hull has no slot with that key.

Throws

If slotKey is not a string, or module fails any of the conditions above — null/undefined (e.g. a getModuleBySymbol miss), not an outfitting module, an uncatalogued symbol, or a missing or non-finite summed stat.

Throws

If the module does not fit the slot (wrong kind, too large, or a restriction the module does not satisfy), conflicts with a one-per-ship family already fitted elsewhere, or worsens a per-ship module-count excess.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
import { CORE_MODULES } from '@elite-dangerous-almanac/core/ships/modules-core';
const fsd = getModuleBySymbol('Int_Hyperdrive_Size6_Class5', CORE_MODULES)!;
const tank = getModuleBySymbol('Int_FuelTank_Size6_Class3', CORE_MODULES)!;
build.setModule('FrameShiftDrive', fsd).setModule('Slot01_Size7', tank);

setModuleEnabled()

setModuleEnabled(slotKey, on): this

Defined in: src/ships/ship-loadout.ts:2290

Switch a fitted module on or off.

Parameters

slotKey

string

The slot's journal key, e.g. "PowerPlant", matched case-insensitively.

on

boolean

true to power it, false to switch it off.

Returns

this

this, for chaining.

Throws

If the slot is empty.

Throws

If slotKey is not a string.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.setModuleEnabled('TinyHardpoint6', false); // an unpowered heat sink

setModulePriority()

setModulePriority(slotKey, priority): this

Defined in: src/ships/ship-loadout.ts:2306

Set a fitted module's power-priority group.

Parameters

slotKey

string

The slot's journal key, matched case-insensitively.

priority

number

The journal's zero-based group, 04. Note that the outfitting panel — and BuildMetrics.powerBudget's bands[].priority — number the same five groups 15.

Returns

this

this, for chaining.

Throws

If the slot is empty, or priority is not an integer in [0, 4].

Throws

If slotKey is not a string.


setPreEngineeredVariant()

setPreEngineeredVariant(slotKey, variant): this

Defined in: src/ships/ship-loadout.ts:2177

Fit a pre-engineered variant into a slot, replacing whatever is there.

The variant's fixed stats and journal engineering block are resolved together. Articles carry Level, Quality: 1, any baked experimental effect and their fixed modifiers. Because the variant names its base module, a decorative identity cannot be applied to an unrelated damage-bearing module. A Mercenary variant whose fixed modifier block has not been published retains the stock catalogue stats and omits Modifiers rather than claiming it changes none.

Parameters

slotKey

string

The slot key to fit into, matched case-insensitively.

variant

PreEngineeredVariant

The pre-engineered catalogue variant to fit.

Returns

this

this, for chaining.

Throws

If variant is not a pre-engineered variant or one of its authored modifier labels cannot be resolved for its base module.

Throws

If no catalogue row matches the supplied module, blueprint, grade, experimental effect and acquisition route.

Throws

If the variant's base module does not fit the slot or violates a fitted-module limit.

Example

import { getPreEngineeredVariants } from '@elite-dangerous-almanac/core/ships/pre-engineered';
import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

const festive = getPreEngineeredVariants('Hpt_FlakMortar_Turret_Medium')
    .find((variant) => variant.blueprintSymbol === 'Decorative_Red')!;
const build = ShipLoadout.empty('Krait_MkII')
    .setPreEngineeredVariant('MediumHardpoint1', festive);
build.fittedModuleAt('MediumHardpoint1')?.effectiveStats?.damage; // -> 0.34

slots()

slots(kind?): readonly LoadoutSlot[]

Defined in: src/ships/ship-loadout.ts:1048

Frozen point-in-time views of the hull's mounts in outfitting-panel order.

Parameters

kind?

SlotKind

Optionally keep only one mount kind. Omit it for every mount.

Returns

readonly LoadoutSlot[]

Detached, frozen slot views. Repeated reads for the same kind reuse the same snapshots until a state-changing edit.

Example

import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

const emptyHardpoints = ShipLoadout.empty('Sidewinder').slots('hardpoint');
emptyHardpoints.every((slot) => slot.module === null); // true

toLoadoutEvent()

toLoadoutEvent(options?): LoadoutEvent

Defined in: src/ships/ship-loadout.ts:2364

This build as a journal Loadout event — the data half of a SLEF entry.

Parameters

options?

LoadoutExportOptions = {}

Module ordering and how sparse to be about power state.

Returns

LoadoutEvent

A fresh event. Every top-level figure is recomputed from the hull and the fitted modules rather than echoed from whatever an import supplied — the one exception being the credits, when credits: 'source' asks for the capture's own. Any figure that cannot be worked out is left out rather than emitted as a stale or zero value — SLEF requires nothing beyond Ship and Modules.

Credits are quoted at retail by default: the bare hull's hullCost plus every fitted module's catalogue list price, with Rebuy 5% of the two. A source's own HullValue / ModulesValue / Value figures are deliberately not quoted here, because they record one commander's purchase history — the Deep Black's modules are all 12.25% off list — and purchase discounts are not a property of the build. They are not lost either: pass credits: 'source' to export the sourcePurchase record instead, as provenance rather than as a price.

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

const event = build.toLoadoutEvent();
event.MaxJumpRange; // recomputed, not the exporter's claim
event.HullValue;    // the catalogue's list price

build.toLoadoutEvent({ credits: 'source' }).HullValue; // what the capture paid

toSlef()

toSlef(options): Slef

Defined in: src/ships/ship-loadout.ts:2405

This build as a one-entry SLEF export.

Parameters

options

SlefExportOptions

Ordering, power state, and the envelope header.

Returns

Slef

The export. Several builds travel together as toSlef([a.toLoadoutEvent(), b.toLoadoutEvent()]) using the function of the same name from ./slef.


toSlefString()

toSlefString(options): string

Defined in: src/ships/ship-loadout.ts:2422

This build as SLEF JSON — ready to write to a file or put on the clipboard.

Parameters

options

SlefExportOptions

As toSlef, plus indent (compact by default).

Returns

string

Example

import type { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

declare const build: ShipLoadout;

build.toSlefString({ header: { appName: 'MyApp', appVersion: '1.0.0' } });

validation()

validation(): LoadoutValidation

Defined in: src/ships/ship-loadout.ts:981

Structural validity and operational completeness of this build.

Returns

LoadoutValidation

The validation report, recomputed from the current fit on every call.

Remarks

valid asks whether the fit is legal: a module in a nonexistent or incompatible slot, a duplicated exclusive family, a module count past the build's allowance, or a ship heavier than its own thrusters can move makes it false. complete asks that and whether armour and the seven core mounts are filled — every build fills those, so on a build the two answers agree. Neither question reports import normalization, so read importOutcomes beside them.

The thruster rule weighs the fitted thrusters' post-engineering maxMass against what the ship comes to at each load it can reach without being re-fitted: unladenMass alone, then with a full main tank, then with a full hold as well. The lightest of those that is already too heavy is what gets reported. A ship that cannot move on a full tank is an error — it never leaves the pad, where the tank always is one — while a ship that only fails with the hold full is a warning, and leaves the build valid and complete: how much cargo to take is the pilot's call. Either way BuildMetrics.mobilityMetrics reports a speed of zero at the load in question.

A capture may state a mass nobody can weigh — a negative UnladenMass, or an engineering modifier that drives a rating below zero. Neither is refused here: this method reports a build rather than rejecting one, so an unweighable figure is left out and the rule it feeds simply does not run. The figure itself is still reported, as a thrown one, by whichever BuildMetrics calculation reads it.


default()

static default(shipSymbol): ShipLoadout

Defined in: src/ships/ship-loadout.ts:770

Start a new build with the modules supplied on a stock ship.

Parameters

shipSymbol

string

The hull's internal symbol, e.g. "SideWinder" (case-insensitive).

Returns

ShipLoadout

A complete, ready-to-edit stock loadout. The build is independent of the frozen shared catalogue: edits affect this instance only.

Throws

If shipSymbol is not a string, or no default loadout exists for that hull.

Remarks

This batteries-included factory resolves calculations through the complete module catalogue already used by ShipLoadout. If only the stock slot/module identities are needed, getDefaultLoadout from ./default-loadouts avoids that cost.

Example

import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

const stock = ShipLoadout.default('SideWinder');
stock.validation().complete; // -> true
stock.fittedModuleAt('FrameShiftDrive')?.symbol;
// -> 'Int_Hyperdrive_Size2_Class1'

empty()

static empty(shipSymbol): ShipLoadout

Defined in: src/ships/ship-loadout.ts:720

Start a new build for a hull with only its stock core modules fitted.

Parameters

shipSymbol

string

The hull's internal symbol, e.g. "Anaconda" (case-insensitive).

Returns

ShipLoadout

A loadout on the hull's stock bulkhead, core internals and cargo hatch, with every hardpoint, utility mount and optional internal left open. Use default for a build that also carries the hull's stock weapons and optional internals.

Throws

If shipSymbol is not a string, or no hull with that symbol has a known slot layout.

Example

import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';

ShipLoadout.empty('Sidewinder').slots('hardpoint').length; // -> 2

fromLoadout()

static fromLoadout(event): ShipLoadout

Defined in: src/ships/ship-loadout.ts:669

Build from a bare journal Loadout event (the data half of a SLEF entry).

Parameters

event

LoadoutEvent

A Loadout event object.

Returns

ShipLoadout

The loadout.

Remarks

Capture and instance state (timestamp, ShipID, HullHealth, Hot) and engineering provenance (Engineer, EngineerID, BlueprintID) stay out of the durable build. A pre-engineered article — a reward, a Mercenary purchase, a Guardian weapon — is identified where the capture's evidence names one uniquely, and the catalogue's stat block then supplies the values the capture omits; the capture's own modifiers stay authoritative over it.

Modules are imported as one complete snapshot, so their order does not affect per-ship count allowances. An entry stands as the event stated it when the mount can hold the article the catalogue resolves, when its slot is a known cosmetic or hull-geometry key (PaintJob, ShipCockpit, a numbered decal, …), or when it is the built-in cargo hatch. Everything else is normalized, and every change is recorded by importOutcomes: an unresolved module in a removable mount is discarded, while armour, the seven core internals and the cargo hatch are filled from the hull defaults whenever the event left no article that mount can hold — an unresolved symbol, a resolved one the mount refuses, and no entry at all are corrected alike, each keeping the source's On, Priority and Health. A removable mount may stand empty, so an article it refuses stays where the event put it and is reported by validation() instead.

Normalization makes the captured aggregates untrustworthy, so they are dropped: unladenMass, cargoCapacity and fuelCapacity are recomputed from the fit that remains, modulesValue and rebuy read null, and sourcePurchase still reports what the capture stated. A mount stocked from absence is the exception where its stock article is free and weightless — the bulkhead and the cargo hatch both are — and every figure stands.

Use this factory rather than replaying a complete loadout through the incremental setModule editor.

Throws

If the event is not shaped like one. What is checked is the structure a build is assembled from and the fields that name things in it: event must be an object with an array of module objects in Modules, each carrying a string Slot and Item, no two claiming the same slot; event.Ship must name a known hull; an Engineering block must be an object and its Modifiers an array of objects each carrying a string Label, whenever the key is there at all; that block's BlueprintName and ExperimentalEffect must be strings when they carry a value. A modifier's Label is required rather than checked-when-present because it is the only thing saying which stat moved. Every remaining field — every number, every flag, a modifier's value beside its label — is trusted, so use ShipLoadout.fromSlef (or parseSlef) for input you did not produce, which reports all of them.


fromSlef()

static fromSlef(input, index?): ShipLoadout

Defined in: src/ships/ship-loadout.ts:602

Build from a SLEF export.

Parameters

input

unknown

The SLEF JSON string, or an already-parsed SLEF object (see parseSlef for accepted shapes).

index?

number = 0

Which entry to take when the export holds several builds. Defaults to the first.

Returns

ShipLoadout

The loadout for that entry.

Remarks

Module normalization follows ShipLoadout.fromLoadout; inspect importOutcomes for modules that were emptied or defaulted.

Throws

If input is a string that is not valid JSON.

Throws

If the export holds no usable loadout, index is out of range, or the selected entry names a hull absent from the catalogue.

API

Guides
astro
Classes (1)
ProceduralSystem

Properties

Accessors

Methods

Interfaces (16)
Type Aliases (3)
Variables (11)
Functions (37)
Subpath modules (3)
commodities
Interfaces (1)
Type Aliases (1)
Variables (3)
Functions (3)
equipment
Interfaces (6)
Type Aliases (8)
Variables (3)
Functions (10)
Subpath modules (2)
i18n
Interfaces (1)
Type Aliases (1)
Functions (17)
materials
Enumerations (2)
Interfaces (2)
Type Aliases (2)
Variables (9)
Functions (9)
ships
Classes (3)
BuildMetrics

Methods

LoadoutEditError

Constructors

Properties

Methods

ShipLoadout

Accessors

Methods

Interfaces (125)
Type Aliases (44)
Variables (10)
Functions (85)
Subpath modules (8)

Clone this wiki locally