EVEShip.fit's Dogma Engine
This library calculates accurately statistics of an EVE Online ship fit.
The input are several data-files provided by EVE Online, together with a ship fit. The output are all the Dogma attributes of the ship, its items and the character.
Implementation
This Dogma engine implements a multi-pass approach.
- pass 1: collect all the Dogma attributes of the hull and modules.
- pass 2: collect all the Dogma effects of the hull and modules.
- pass 3: apply all the Dogma effects to the hull/modules, calculating the actual Dogma attribute values.
- pass 4: augment the Dogma attributes with EVEShip.fit specific attributes, that are too complex for the Dogma itself to handle.
Input and output
calculate takes a fit and options, and returns a calculation.
All identifiers are those from the SDE.
Fit
name(optional): name of the fit.ship: the ship being fitted.type_id: its type.
items: everything fitted or carried. Each item has:type_id: its type.slot: where the item is.type:high,medium,low,rig,subsystem,service,fighter_tube,fighter_bay,drone_bayorcargo.cargois carried, but not calculated.index: position within that slot type, starting at 0. Absent forfighter_bay,drone_bayandcargo.
quantity(optional, default 1): stack size for drones, fighters and cargo. For fighters in a tube, the squadron size.state: requested state;offline,online,activeoroverload.charge(optional): the loaded charge, astype_id.fighter_abilities(optional): the abilities a fighter uses, as effect IDs. Absent means the fighter's default abilities.
character(optional):skills: level (0 to 5) per skill type ID. A missing skill gives no bonuses.
Options
sources(optional, default false): report per attribute what its value was calculated from. Leave it off unless you show it; it makes the calculation several times bigger.
Calculation
ship: result for the ship.items: one result per item of the fit, in the same order.character: result for the character.
Each result has:
-
attributes: per attribute ID, itsbasevalue before effects and its finalvalue. With thesourcesoption, alsosources: every modifier on it, in the order they were applied. Each has:from: where it comes from;typeisship,character,itemorcharge(with theindexintoitems), orskill(with itstype_id).effect_id: the effect that modifies.source_attribute_id: the attribute on the source that holdsvalue.operator:pre_assign,pre_mul,pre_div,mod_add,mod_sub,post_mul,post_div,post_percentorpost_assign.value: the value of the modifying attribute.quantity: how many times it counts. A stacking penalised stack is listed once per item instead.penalty: the stacking penalty factor it got, ornullif not penalised.applied: false when the source's state is too low for the effect.
How much each source added is not reported: multiplications compound and stacking penalties depend on order, so there is no single answer.
-
state: the state the item reached, which can be lower than requested. -
max_state: the highest state the item can reach. -
charge: result for its charge, if it has one.
EVEShip.fit's specific attributes
Pass 4 create Dogma attributes that do not exist in-game, but are rather complicated to calculate.
To make rendering a fit easier, these are calculated by this library, and presented as new Dogma attributes.
Their identifier is always a negative value, to visually separate them. What additional attributes exist are defined in EVEShipFit/sde-patched repository.
Development
Make sure you have Rust installed.
Next, we need the data-files.
They are Flatbuffers, built by sde-patched and published on npm as @eveshipfit/sde:
sde.datholds everything needed to calculate a fit.names.datholds the type names in the other seven languages EVE supports. It is optional.
English names live in sde.dat, so an EFT-fit written in English imports without it; names.dat is only consulted when a name does not match.
After that, we can run the application.
The regression suite reads the same paths; set ESF_SDE and ESF_NAMES to point it elsewhere.
Regression
The engine is locked down by snapshot tests. A case calculates one fit with one set of skills, and compares the result against a stored snapshot in tests/snapshots.
If failures are expected differences, use insta to resolve them:
Integration
Javascript (WebAssembly)
The primary goal of this library is to build a WebAssembly variant that can easily be used in the browser. This means that there is no need for a server-component, and everything can be calculated in the browser.
This is done with wasm-pack:
In the pkg folder is now a NPM module to use.
Javascript hands over sde.dat once, and every lookup after that happens inside WebAssembly.
The file is a Flatbuffer, so nothing is parsed: the bytes are used where they land.
import init from "@eveshipfit/dogma-engine";
await ;
;
const sde = await .;
const buildNumber = ;
const fit = ;
const calculation = ;
/* Or if you want to know the source of the effects: */
const withSources = ;